Social networks
You can find me on:
   
Open sharing content

These articles are available under Creative Commons license BY-SA-3.0

Posts Tagged ‘xml’

The following steps will allow you to develop and deploy a first demo web-app with Glassfish Server 4.
1) To install Glassfish 4.0 follow the steps at http://glassfish.java.net/download.html
For example, you can get the zip version and extract into: C:\glassfish4.

2) If you´re working on a Windows Desktop Rename glassfish4/glassfish/bin asadmin to *.s to prevent the following Maven error:
Unable to start domain "domain1". IOException: Cannot run program"C:\glassfishv3\glassfish\bin\asadmin": CreateProcess error=193, %1 is not a valid Win32-Application

In this way The system will run asadmin.bat, instead of calling the Linux script (provided with no file extension by Glassfish).

3) On Eclipse install Glassfish plugin (https://marketplace.eclipse.org/content/glassfish-tools-kepler) to manage the server graphically. Otherwise you would not be able to installing with the command File>New>Other>Server> etc.
Starting Glassfish for the first time, you will have a user called “admin” with no password. You can manage Glassfish with Admin-Console available at: http://localhost:4848/ or even with asadmin CLI console (under C:\glassfish4\glassfish\bin).

4) To deploy your application using Maven, create the settings.xml file under the .m2 folder (for example, under Windows at the location: C:\Users\username\.m2), providing the glassfish profile credentials: they will automatically imported in the pom.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <profiles>
        <profile>
            <id>glassfish-context</id>
            <properties>
                <local.glassfish.home>C:\\glassfish4\\glassfish</local.glassfish.home>
                <local.glassfish.user>admin</local.glassfish.user>
                <local.glassfish.domain>domain1</local.glassfish.domain>
                <local.glassfish.passfile>
            ${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords
                </local.glassfish.passfile>
            </properties>
        </profile>
    </profiles>
 
    <activeProfiles>
        <activeProfile>glassfish-context</activeProfile>
    </activeProfiles>
</settings>

5) Create a new Maven project with the maven archetype “maven-archetype-webapp” template. As a default you can already find the index.jsp HelloWorld page.

6) Add the following plugins to the pom.xml:

…
<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.1.1</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
					<!-- <webXml>src\main\webapp\WEB-INF\web.xml</webXml> -->
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.glassfish.maven.plugin</groupId>
				<artifactId>maven-glassfish-plugin</artifactId>
				<version>2.1</version>
				<configuration>
				<glassfishDirectory>${local.glassfish.home}</glassfishDirectory>
					<user>admin</user>
					<passwordFile>${local.glassfish.passfile}</passwordFile>
					<domain>
						<name>domain1</name>
						<httpPort>8080</httpPort>
						<adminPort>4848</adminPort>
					</domain>
					<components>
						<component>
							<name>${project.artifactId}</name>
					<artifact>target/${project.build.finalName}.war</artifact>
						</component>
					</components>
					<debug>true</debug>
					<terse>false</terse>
					<echo>true</echo>
				</configuration>
			</plugin>

		</plugins>
		<finalName>Glassfish_HelloWorld</finalName>
	</build>
</project>

7) Launch the maven command:
clean package glassfish:deploy

You may find errors related to the Dynamic Web Module in the Eclipse project, even if the maven gives you “BUILD SUCCESS”. For now it´s ok.

With the given pom.xml the application will be deployed into:
C:\glassfish4\glassfish\domains\domain1\applications

You can see it up and running at: http://localhost:8080/Glassfish_HelloWorld/

You can manage the applications, for example editing the Content Root folder, directly in the administration console.

Demo Code available at:
http://sourceforge.net/p/mavendemo/code/HEAD/tree/GlassfishHelloWorld/

After using JAXB with XSD schema, I have finally discovered that it´s MUCH better to make it with files and jaxd binding files.

Supposing you want to generate the classes for a web-app xml file, in the Maven pom.xml you need to add something like:

<plugin>
  <groupId>org.jvnet.jaxb2.maven2</groupId>
   <artifactId>maven-jaxb2-plugin</artifactId>
      <executions>
 	<execution>
        	<goals>
	        	<goal>generate</goal>
		</goals>
		<configuration>
		<!-- if you want to put DTD somewhere else <schemaDirectory>src/main/jaxb</schemaDirectory> -->
			<schemaDirectory>src/main/resources/web</schemaDirectory>
			   <generateDirectory>${basedir}/src/main/java</generateDirectory>
				<packagename>com.my.package</packagename>
		 		    <extension>true</extension>
					<schemaLanguage>DTD</schemaLanguage>
					    <schemaIncludes>
						<schemaInclude>*.dtd</schemaInclude>
					    </schemaIncludes>
					<bindingIncludes>
					    <bindingInclude>*.jaxb</bindingInclude>
						</bindingIncludes>
						<args>
						   <arg>-Xinject-listener-code</arg>
						</args>
						</configuration>
					</execution>
				</executions>
		<dependencies>
			<dependency>
				<groupId>org.jvnet.jaxb2-commons</groupId>
				<artifactId>property-listener-injector</artifactId>
				<version>1.0</version>
			</dependency>
		</dependencies>
</plugin>

In the specified schema directory there must be both the .dtd and the .jaxb binding files.
To specify a package for the generated classes, in the jaxb file like:

<?xml version="1.0" ?>
     <xml-java-binding-schema xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
  xmlns:ci="http://jaxb.dev.java.net/plugin/listener-injector">
         <options package="deploy.service.webapp" />
            <xjc:serializable/>
    </xml-java-binding-schema>

You can find a full demo of a web-app xml schema classes generation at sourceforge: JAXB DTD maven demo

With JAXB you need to dhandle special characters you can just choose between two options.

Otherwise you need to define your own character handler.

The following class shows you how to handle both CDATA elements and special characters.

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;

import com.sun.xml.bind.marshaller.CharacterEscapeHandler;

public class XmlCharacterHandler implements CharacterEscapeHandler {

	public void escape(char[] buf, int start, int len, boolean isAttValue,
			Writer out) throws IOException {
		StringWriter buffer = new StringWriter();

		for (int i = start; i < start + len; i++) {
			buffer.write(buf[i]);
		}

		String st = buffer.toString();

		if (!st.contains("CDATA")) {
			st = buffer.toString().replace("&", "&amp;").replace("<", "&lt;")
					.replace(">", "&gt;").replace("'", "&apos;")
					.replace("\"", "&quot;");

		}
		out.write(st);
//		System.out.println(st);
	}

}

In your marshaller method just add the following property:

	marshaller.setProperty(CharacterEscapeHandler.class.getName(),
					new XmlCharacterHandler());

Although many XML files have a DOCTYPE declaration, browsing the internet and my safary library account haven´t helped that much to unmarshall (and marshall) my mbeans descriptors with JAXB. It tooks me several hours to find a way out.
Supposing that the xml root element is called “Bean”, you can get the header, simply converting the xml file in a string and taking all the content until the first root element tag (). This might be very useful if you want to scan a folder in which the xml files have different headers (like jboss services configurationes ones).

	public static String getHeader(String filePath) {

		String header = "";
		String xmlContent = "";
		int headerLastIndex = 0;

		File file = new File(filePath);

		String text = "";
		try {
			text = FileUtils.readFileToString(file, "UTF-8");

			headerLastIndex = text.indexOf("<mbean>");
			header = text.substring(0, headerLastIndex);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return header;

	}
	public static void marshaller(Mbean mbean, String filePath, String header)
			throws CustomizerException {

		stringWriter = new StringWriter();

		File file = new File(filePath);
		try {

			jaxbContext = JAXBContext.newInstance(Mbean.class);

			fileWriter = new FileWriter(file);

			marshaller = jaxbContext.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

			marshaller.marshal(mbean, stringWriter);

			System.out.println(stringWriter.toString());

			fileWriter.write(header+stringWriter.toString());

			fileWriter.flush();
			fileWriter.close();

		} catch (MarshalException ex) {

			throw new CustomizerException("Marshalling the file: " + filePath
					+ "not possible. Wrong file content");

		} catch (JAXBException e) {

			throw new CustomizerException("Could not parse the XML file: "
					+ filePath);

		} catch (IOException e) {

			throw new CustomizerException("Couldn´t access the file: "
					+ filePath);
		}

		finally {

			try {
				fileWriter.close();
			} catch (IOException e) {

				throw new CustomizerException(
						"Couldn´t close the fileWriter for: " + filePath);
			}
		}

	}

I would like to make it in a better way with JAXB, but I think that the second version is still a bit raw. Currently there are no unmarshalling properties provided. You can invoke the method setProperty(java.lang.String name, java.lang.Object value), but there are still no properties provided by the API. I would like to contribute to the project…

In this post I will show you how to represent an XSD schema with root attribute and child element with attribute and value. For example, let´s consider a software development team:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<team category="software development">
    <Member role="junior">Laura</Member>
    <Member role="senior">Erik</Member>
    <Member role="graduate">Mike</Member>
</team>

The xsd schema generally represent a a working team :

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://acme.com/schema/type/team/v1" xmlns:team="http://acme.com/schema/type/team/v1"
	xmlns:company="http://acme.com/schema/type/company/v1"
	elementFormDefault="qualified">

	<xsd:element name="Team" type="team:Team" />

	<xsd:complexType name="Team">
		<xsd:annotation>
			<xsd:documentation>Represents a working team </xsd:documentation>
		</xsd:annotation>
		<xsd:sequence maxOccurs="unbounded">
			<xsd:element name="Member">
				<xsd:complexType>
					<xsd:simpleContent>
						<xsd:extension base="xsd:string">
							<xsd:attribute name="role" type="xsd:string" />
						</xsd:extension>
					</xsd:simpleContent>
				</xsd:complexType>
			</xsd:element>
		</xsd:sequence>
		<xsd:attribute name="category" type="xsd:string" />
	</xsd:complexType>
</xsd:schema>

Although it seems to be a typical case, I have spent several hours reading books, tutorials and forum, trying to map a web service xml file with such a structure.
I have finally found the solution on a google forums post.

A better solution would be using the type attribute and make a separate “complexType” tag, because in this way JAXB would be able to create a different bean class for each element (also the nested ones). So an equivalent version of the schema is the following:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://acme.com/schema/type/team/v1" xmlns:team="http://acme.com/schema/type/team/v1"
	xmlns:company="http://acme.com/schema/type/company/v1"
	elementFormDefault="qualified">

	<xsd:element name="Team" type="team:Team" />

	<xsd:complexType name="Team">
		<xsd:annotation>
			<xsd:documentation>Represents a working team </xsd:documentation>
		</xsd:annotation>
		<xsd:sequence>
			<xsd:element name="Member" type="team:member" minOccurs="0"
				maxOccurs="unbounded" />
		</xsd:sequence>
		<xsd:attribute name="category" type="xsd:string" />
	</xsd:complexType>
	
	<xsd:complexType name="member">
		<xsd:simpleContent>
			<xsd:extension base="xsd:string">
				<xsd:attribute name="role" type="xsd:string" />
			</xsd:extension>
		</xsd:simpleContent>
	</xsd:complexType>

</xsd:schema>

In eclipse, downloading the “m2e conntector for jaxb” plugin, you can automatically generate all the object classes from your XSD schema (in the menu bar menu you can find the JAXB section under File>New>…). Without a binding file, you will have to add the “@XmlRootElement” annotation on the top of your root element class and also delete the namespace in the package-info class. I will tell you more in the next posts…

To make a Liferay Service Builder with external database there are some rules to follow. This post will help you to get straight to the point.
Keep in mind that:

  • You can’t deploy more than one portlet mapping column with the same entity name, otherwise you get a hot-Deployment error.
  • the names of the portlet name, namespace and database must be distinct (ex. portlet=”imageview“, namespace=”mammography“, database=”dicomviewer“).
  • when you add external jar, you must add them in the Tomcat/lib/ext
    so liferay can find them in the global classpath.

The steps to make the service builder with the external database mapping are:

  1. make the service.xml file in the /docroot/WEB-INF/
  2. launch the build-service ant command
  3. add the ext-spring.xml file in the /docroot/WEB-INF/src/META-INF/ folder
  4. deploy the portlet.

The example below might be helpful.

—service.xml ————

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.0.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_0_0.dtd">


<service-builder package-path="it.dicom">
<author>Laura Liparulo</author>
<namespace>mammography</namespace>

<entity name="Volume" local-service="true" remote-service="true" table="volume"
data-source="mammographyDataSource" session-factory="mammographySessionFactory" tx-manager="mammographyTransactionManager">
<!-- PK Fields -->
<column name="volumeId" type="long" primary="true" />
<!-- Other Fields -->
<column name="volumeName" type="String" />
<!-- Relationships -->
<column name="caseVolume" type="Collection" entity="CaseArchive"
mapping-key="volumeId" />
<order by="asc">
<order-column name="volumeName" />

</order>
<finder name="Volume_Name" return-type="Collection">
<finder-column name="volumeName" />
</finder>
</entity>

<entity name="CaseArchive" local-service="true" remote-service="true" table="case_archive"
data-source="mammographyDataSource" session-factory="mammographySessionFactory" tx-manager="mammographyTransactionManager">
<!-- PK Fields -->
<column name="caseId" type="long" primary="true" />
<!-- Other Fields -->
<column name="caseName" type="String" />
<column name="volumeId" type="long" />
<column name="notes" type="String" />
<!-- Relationships -->
<column name="image_Case" type="Collection" entity="Image"
mapping-key="caseId" />
<order by="asc">
<order-column name="caseName" />
</order>
<finder name="Case_Name" return-type="Collection">
<finder-column name="caseName" />

</finder>
</entity>

</service-builder>
;

—ext-spring.xml ————

<?xml version="1.0"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean
class="
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
</bean>
<bean id="mammographyDataSourceTarget"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/dicomviewer" />
<property name="username" value="root" />

<property name="password" value="tigertailz" />
</bean>
<bean id="mammographyDataSource"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<ref bean="mammographyDataSourceTarget" />
</property>
</bean>
<bean id="mammographyHibernateSessionFactory"
class="com.liferay.portal.spring.hibernate.PortletHibernateConfiguration">
<property name="dataSource">
<ref bean="mammographyDataSource" />
</property>
</bean>
<bean id="mammographySessionFactory">
<property name="sessionFactoryImplementor">
<ref bean="mammographyHibernateSessionFactory" />

</property>
</bean>
<bean id="mammographyTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="dataSource">
<ref bean="mammographyDataSource" />
</property>
<property name="sessionFactory">
<ref bean="mammographyHibernateSessionFactory" />
</property>
</bean>
</beans>

Now you can make it fast as a shark! 🙂