Showing posts with label xml. Show all posts
Showing posts with label xml. Show all posts

Thursday, January 25, 2007

MM7 schema binding dengan JAXB

MM7 schema binding dengan JAXB

Ini adalah pengalaman saya menggunakan JAXB untuk men-generate class source code untuk MM7.
MM7 merupakan spesifikasi untuk mengirimkan MMS ke MMSC menggunakan XML SOAP. MM7 biasanya digunakan untuk menghubungkan content provider dengan operator telco.
Contoh ini mungkin berguna bagi yang mulai mencoba menggunakan JAXB dan menemui kesulitas dengan error yang sama.

Untuk membuat source code dari schema file (xsd) dengan meggunakan JAXB, gunakan perintah xjc.bat atau xjc.sh
Pertama kali yang saya lakukan untuk melakukan binding XML schema ke java code adalah dengan perintah seperti berikut:


C:\USERS\ejlp>%JWSDP_HOME%\jaxb\bin\xjc.bat -nv -extension REL-5-MM7-1-2.xsd

REL-5-MM7-1-2.xsd adalah file XML schema MM7 dan %JWSDP_HOME% adalah environtment varibel dari Java Web Service Developer Pack terinstal.
Yang saya dapat dari perintah diatas adalah pesan error seperti dibawah ini:


Warning: JAVA_HOME environment variable is not set.
If build fails because sun.* classes could not be found
you will need to set the JAVA_HOME environment variable
to the installation directory of java.

parsing a schema...
[WARNING] warning: <anyAttribute> ignored
line 48 of
[WARNING] warning: <anyAttribute> ignored
line 56 of
[WARNING] warning: <anyAttribute> ignored
line 64 of
[WARNING] warning: "final" attribute of <complexType> is not supported
line 99 of
[WARNING] warning: <anyAttribute> ignored
line 117 of
[WARNING] warning: <anyAttribute> ignored
line 324 of REL-5-MM7-1-2.xsd
[ERROR] A class/interface with the same name "org.xmlsoap.schemas.soap.envelope.Envelope" is already in use.
Use a class customization to resolve this conflict.
line 42 of
[ERROR] (Relevant to above error) another "Envelope" is generated from here.
line 41 of
[ERROR] A class/interface with the same name "org.xmlsoap.schemas.soap.envelope.Body" is already in use.
Use a class customization to resolve this conflict.
line 60 of
[ERROR] (Relevant to above error) another "Body" is generated from here.
line 59 of
[ERROR] A class/interface with the same name "org.xmlsoap.schemas.soap.envelope.Fault" is already in use.
Use a class customization to resolve this conflict.
line 99 of
[ERROR] (Relevant to above error) another "Fault" is generated from here.
line 98 of
[ERROR] A class/interface with the same name "org.xmlsoap.schemas.soap.envelope.Header" is already in use.
Use a class customization to resolve this conflict.
line 52 of
[ERROR] (Relevant to above error) another "Header" is generated from here.
line 51 of
Failed to parse a schema.


Saya abaikan pesan warning, saya cuma concern pada pesan error yang saya kira membuat file source java tidak terbuat. Error tersebut terjadi karena ada konflik penamaan. JAXB akan membuat class dengan nama yang sama, dalam hal ini adalah Envelope, Body, Fault dan Header.

Setelah mencari informasi penyebab error tersebut maka saya mendapatkan solusi yaitu dengan membuat file binding.xjb yang merupakan konfigurasi binding yang harus dilakukan JAXB. Dalam file yang dibuat tersebut, saya buat agar setiap class yang akan di-generate dengan package org.xmlsoap.schemas.soap.envelope dari elemen bernama Fault akan diberinama SOAPFault bukan Fault, dan yang dari elemen Header akan diberinama SOAPHeader bukan Header, begitu juga dengan elemen Body dan Envelope.

Dibawah ini adalah isi dari file binding.xjb

   
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="http://schemas.xmlsoap.org/soap/envelope/" node="/xs:schema">

<jxb:schemaBindings>
<jxb:package name="org.xmlsoap.schemas.soap.envelope"/>
<jxb:nameXmlTransform>
<jxb:elementName suffix="Element"/>
</jxb:nameXmlTransform>
</jxb:schemaBindings>

<jxb:bindings node="//xs:element[@name='Fault']">
<jxb:class name="SOAPFault"/>
</jxb:bindings>

<jxb:bindings node="//xs:element[@name='Header']">
<jxb:class name="SOAPHeader"/>
</jxb:bindings>

<jxb:bindings node="//xs:element[@name='Body']">
<jxb:class name="SOAPBody"/>
</jxb:bindings>

<jxb:bindings node="//xs:element[@name='Envelope']">
<jxb:class name="SOAPEnvelope"/>
</jxb:bindings>

</jxb:bindings>

</jxb:bindings>

Setelah itu saya jalankan lagi perintah ditas tadi dengan menggunakan file konfigurasi binging bernama binding.xjb.
Dengan konfigurasi diatas, tidak terjadi lagi konfilik penamaan class.

C:\USERS\ejlp>%JWSDP_HOME%\jaxb\bin\xjc.bat -nv -extension REL-5-MM7-1-2.xsd -b binding.xjb

Thursday, November 16, 2006

Format file presentasi pada MMS

Beberapa handphone saat ini sudah memiliki fitus pembuatan presentasi sederhana. Presentasi tersebut dapat berisi teks, gambar maupun suara dan kemudian dapat dikirimkan ke handphone lain menggunakan MMS (Multimedia Messaging Service).

Teknologi presentasi pada MMS merupakan standard yang dibuat oleh OMA (Open Mobile Alliance). Teknologi ini menggunakan SIML (dibaca seperti kata smile) yaitu sepesifikasi (rekomendasi) dari W3C.

SMIL adalah singkatan Synchronized Multimedia Integration Language, dari namanya kita tahu teknologi ini menyatukan beberapa atau banyak multimedia resource.Format SMIL seperti HTML, merupakan suatu file teks dengan link yang merujuk ke suatu sumber (resource) tertentu. Resource tersebut bisa teks file, audio, gambar maupun video. Tentu saja untuk mepresentasikan suatu file SMIL dibutuhkan program (client) yang dapat membaca dan memproses file tersebut. Pada komputer destop, program seperti RealPlayer merupakan salah satu contoh SMIL client.

SIML yang digunakan pada MMS adalah subset dari versi asli SMIL karena terbatasnya kapabilitas dari suatu handphone atau mobile device. Oleh karena itu kita hanya bisa membuat presentasi yang sederhana pada handphone.

Contoh suatu file SIML:

<smil>
<body>
<par dur="10000ms">
<text src="deskripsi.txt"></text>
<audio src="deskripsi.rm"></audio>
<img src="deskripsi.jpg"></img>
</par>
</body>
</smil>
</code>

Thursday, July 13, 2006

SAX Tutorial

-== Pengenalan SAX ==-

SAX (Simple API for XML) adalah API (common interface) untuk memparsing XML dokumen secara event-based.
SAX bukanlah sebuah XML parser. SAX didesain untuk dapat digunakan dengan berbagai macam event-based parser.

SAX tidak sulit dipelajari, karena sifatnya yang simpel.
SAX API cukup kecil, hanya terdiri 35 class/interface yang terdapat dalam 3 package:

org.xml.sax
org.xml.sax.ext
org.xml.sax.helpers

-== Event-based API ==-

Pada event-based API,suatu even akan dilemparkan lewat callback jika parser membaca karakter data atau awal/akhir
dari dokumen maupun element/tag.Kita harus membuat (mengimplementasikan) handler yang akan menangani event. Dengan
event-based API, akses ke XML dokumen menjadi lebih cepat dan sederhana. Juga dimungkinakan untuk memparsing
dokumen yang besar dari memori sistem yang tersedia karena struktur dokumen tidak disimpan dalam memori.

Catatan
Untuk yang belum tahu, selain parser yang event based ada juga parser XML yang DOM based dan pull streaming based.
Ketiga macam parser tersebut dibedakan dengan caranya memproses dokumen XML dan masing masing memiliki kelebihan dan
kekurangan.


-== Beberapa Java SAX2 parser ==-

Xerces http://xml.apache.org/xerces-j/index.html
Sun's JAXP http://java.sun.com/xml/
SAXON XSLT processor http://users.iclway.co.uk/mhkay/saxon/
Oracle XML Developer's Kit for Java http://technet.oracle.com/tech/xml/xdk_java.html
ParserAdapter http://www.megginson.com/SAX/Java/index.html

-== Menggunakan SAX ==-

Untuk dapat melakukan parsing pada XML dokumen kita membutuhkan class yang mengimplentasikan interface XMLReader.
XMLReader bertanggung jawab untuk mem-parsing dokumen XML.
Implemantasi interface org.xml.sax.XMLReader dapat di-instantiate dengan cara:

XMLReader xr = (XMLReader) Class.forName("org.apache.xerces.parsers.SAXParser").newInstance();

atau

XMLReader xr = new org.apache.xerces.parsers.SAXParser();

atau

XMLReader xr = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();

Dianjurkan kita menggunakan cara yang terakhir, karena tidak tergantung pada suatu implementasi parser tertentu.
Dengan cara yang terakhir, XMLReader didapatkan dari class pada saat runtime dengan membaca setting pada:

- System property "org.xml.sax.driver" yang dispesifikasikan pada command line seperti

java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser JavaProgram

atau pada kode program seperti

System.setProperty("org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser");

- Atau pada file META-INF/services/org.xml.sax.driver didalam JAR file


XMLReader membutuhkan class handler yang harus mengimplementasikan interface berikut:

- ContentHandler yang akan meng-handle jika terjadi event pada saat proses parsing
- ErrorHandler yang akan meng-handle jika terjadi warning/error
- DTDHandler yang akan meng-handle event pada dkumen DTD
- EntityResolver yang akan men jika ada external entities pada dokument XML (misalnya external DTD atau external
parameter entity)


Untuk mengimplementasikan handler diatas sebaiknya gunakan DefaultHandler sebagai base class.
DefaultHandler telah mengimplementasikan keempat interface diatas.
Method signature dari ContentHandler (atau Defaulthandler) yang penting untuk memproses dokumen XML diantaranya:

* void characters(char[] ch, int start, int length)
* void endDocument()
* void endElement(String uri, String localName, String rawName)
* void startDocument()
* void startElement(String uri, String localName, String rawName, Attributes attributes)

Dibawah ini contoh code penggunaan DefaultHandler sebagai base class yang hanya mengimplementasikan method-method
ContentHandler:

public class MyDefaultHandler extends DefaultHandler {
public void startElement(java.lang.String uri, String localName, String qName, Attributes attributes)
throws SAXException {
System.out.print("Start element: URI = " + uri +
", localname = " + localName +
", qname = " + qName +
", attributes = {" );
for (int i = 0; i < attributes.getLength(); i++) {
System.out.print( attributes.getQName(i) + "(" + attributes.getType(i) + ") = " +
attributes.getValue(i) + ", ");
}
System.out.println("}");
}


public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println("characters: " + ch);
}

public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("End element: URI = " + uri + ", localname = " + localName + ", qname = " + qName);
}

}


XML memerlukan class InputSource sebagai input dalam melakukan parsing.
InputSource adalah representasi dari XML dokumen yang kemudian di-parsing oleh XMLReader.
XML dokumen dapat berada di lokal maupun remote dan URI digunakan sebagai parameter constructor dari class InputSource.

FileInputStream is = new FileInputStream("C:/Users.xml");
xmlReader.setContentHandler(myDefaultHandler);
xmlReader.parse(new InputSource(is));

-== Perubahan class pada SAX1 ke SAX2 ==-

Saat ini SAX terbaru adalah versi 2, biasa ditulis SAX2 dan SAX versi sebelumnya biasa ditulis SAX1.
Ada beberapa perbedaan antara SAX1 dan SAX2 walaupun demikian parser yang mengimplementasikan SAX1 yaitu class Parser
masih dapat digunakan oleh SAX2, demikian juga sebaliknya.
Dibawah ini adalah table class yang berubah pada SAX1 ke SAX2

-------------------------------------
Class pada SAX1 Class pada SAX2
================= ===================
ParserFactory XMLReaderFactory
Parser XMLReader
DocumentHandler ContentHandler
HandlerBase DefaultHandler
AttibuteList Attributes
-------------------------------------

Parser dari SAX1 dapat digunakan pada sebagai SAX2 XMLReader dengan menggunakan class ParserAdapter

SAX2 XMLReader juga dapat digunakan sebagai XA1 Parser dengan menggunakan class XMLReaderAdapter

-== Contoh kode yang lengkap ==-

public class MyDefaultHandler extends DefaultHandler {

public static void main(String[] args) {
try
FileInputStream is = new FileInputStream("C:/Users.xml");
XMLReaderFactory fact = XMLReaderFactory.newInstance();
XMLReader xmlReader = parser.createXMLReader();
xmlReader.setContentHandler(this);
xmlReaderreader.setErrorHandler(this);
xmlReader.setFeature("http://xml.org/sax/features/validation" ,true);
xmlReader.setEntityResolver(this);
xmlReader.parse(new InputSource(is));
} catch (Exception e) {
e.printStackTrace();
}
}


public void startElement(java.lang.String uri, String localName, String qName, Attributes attributes)
throws SAXException {
System.out.print("Start element: URI = " + uri +
", localname = " + localName +
", qname = " + qName +
", attributes = {" );
for (int i = 0; i < attributes.getLength(); i++) {
System.out.print( attributes.getQName(i) + "(" + attributes.getType(i) + ") = " +
attributes.getValue(i) + ", ");
}
System.out.println("}");
}


public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println("characters: " + ch);
}

public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("End element: URI = " + uri + ", localname = " + localName + ", qname = " + qName);
}



}



-== Menggunakan JAXP (versi 1.1) ==-

Pada JAXP, XMLReader dibungkus (wrap) oleh class lain yaitu javax.xml.parsers.SAXParser yang dapat diperoleh dari
factory class yaitu javax.xml.parsers.SAXParserFactory. Dibawah ini contoh kode untuk mendapatkan instance dari class
SAXParser:

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();

Class SAXParser sudah cukup untuk dapat melakukan parsing pada XML dokumen, yaitu dengan menggunakan method
parse(InputSource, DefaultHandler). Jika menginginkan mendapatkan class XMLReader, kita dapat memanggil method
getXMLReader() pada class SAXParser.

SAXParserFactory adalah class abstract, implementasinya didapatkan dari metode lookup yaitu:

- Menggunakan system property "javax.xml.parsers.SAXParserFactory"
- Menggunakan standar java properties file yang ada di "lib/jaxp.properties" pada direktori JRE
- Menggunakan service API yaitu pada file META-INF/services/javax.xml.parsers.SAXParserFactory di dalam file JAR
- Default instance yang ada pada platform

Friday, May 06, 2005

Java XML-RPC, gampang banget...

Ingin membuat aplikasi client-server? tidak mau membuat web service karena terlalu ribet? tidak mau terlalu banyak coding dengan RMI? coba XML-RPC menggunakan Apache XML-RPC

Apache XML-RPC mudah digunakan. Hanya dengan sedikit coding kita sudah bisa membuat aplikasi client-server. Bisa menggunakan Built-in HTTP Server sebagai server atau kita juga bisa membuat servlet yang di-deploy di web server (servlet container).

Langkah pertama membuat class handler yang akan menjadi class pemroses (processor) dari setiap request. Contoh :
 public class Messenger {
public String send(String address, String message) {
// process sending message here
return "Sending successful to " + address+ " message is \"" + message + "\"";
}
}
Lalu buat server:
  import org.apache.xmlrpc.WebServer;
public class XmlRpcServer {
public static void main(String[] args) {
try {
WebServer webServer = new WebServer(7777);
webServer.addHandler("MyMessanger", new Messenger());
webServer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Setelah itu jalankan server, dan buat client:
  import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Vector;
import org.apache.xmlrpc.XmlRpcClient;
import org.apache.xmlrpc.XmlRpcException;
public class SmsEngineClient {
public static void main(String[] args) {
try {
XmlRpcClient client = new XmlRpcClient("http://localhost:7777");
Vector params = new Vector ();
params.addElement("friend");
params.addElement ("Apa kabar euy?");
String result = (String) client.execute("MyMessanger.send", params);
System.out.println(result);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (XmlRpcException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Jalankan program client, dan lihat hasilnya. Mudah sekali.

Dengan XML-RPC kita bisa dengan mudah melakukan pertukaran data dengan tipe:
int, boolean, java.lang.String, double, java.util.Date, java.util.Hashtable, java.util.Vector dan byte[] (byte array, untuk pengiriman file misalnya).

Jadi kenapa tidak pakai XML-RPC saja?

Wednesday, March 30, 2005

Seperti XML, tetapi bukan

Ada yang bilang XML tidak benar-benar human readable, XML kurang efisien, karenanya beberapa orang membuat alternatif penggati XML yang lebih sederhana dan mudah. Tapi tetap saja XML memiliki kelebihan dari sisi iteroperability, kemudahan mendapatkan library untuk processing-nya (parser), kalaupun kurang simple sudah banyak tool (editor) untuk memanipulasi XML.

Beberapa alternatif pengganti XML diataranya:


Followers