January 28, 2007
Windows LaTeX Editor
Sicher hat OpenOffice den Vorteil eines WYSIWYG Editors, wo man gleich sieht, wie das Geschriebene aussieht. LaTeX mit seiner Syntax ist da schon kryptischer. Bisher habe ich noch keinen vernünftigen Editor für LaTeX unter Windows gefunden, der diesen Nachteil gegenüber Office Programmen ausgleichen konnte.
Jedoch bin ich vor einiger Zeit auf den Editor LEd gestoßen. LEd verfügt über eine integrierte DVI Vorschau. Zwar muss noch kompiliert werden, bevor das Dokument angezeigt wird, aber die paar Sekunden kann ich warten.
January 22, 2007
Web Service mit Java 6
Um eine Klasse als Web Service zu kennzeichnen wird sie mit der Annotation
javax.jws.WebService
und Service Methoden mit javax.jws.WebMethod
markiert. Außerdem muss der Web Service veröffentlicht werden. Hier hilft die Klasse javax.xml.ws.Endpoint
, die eine statische Methode publish(String address, Object implementor)
zur Verfügung stellt.
package webservicetest;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.xml.ws.Endpoint;
@WebService
public class CalculatorService{
@WebMethod
public int duplicate(int value){
return value * 2;
}
public static void main(String[] args) {
Endpoint.publish("http://localhost:8080/Calculator", new CalculatorService());
}
}
Startet man die
main
Methode dieser Klasse, ist der Web Service unter der URL http://localhost:8080/Calculator
so lange verfügbar bis das Programm terminiert. Als Test kann die URL http://localhost:8080/Calculator/rate?WSDL
aufgerufen werden. Im Browser erscheint daraufhin eine Beschreibung des Services im WSDL Format.Mehr Informationen und weitere Möglichkeiten finden sich in der Java 6 API.
January 7, 2007
[FeedCreator] RSS-Feed mit PHP
Diese Frage stellte ich mir vor Kurzem auch. Nach etwas googeln, habe ich relativ schnell eine Antwort gefunden.
Deshalb möchte ich die Implementierung des RSS 2.0 Feeds nicht im Einzelnen beschreiben, sondern das PHP Skript hier zum herunterladen bereitstellen.
Aufbau
RSS verlangt eine bestimmte XML Struktur (siehe RSS 2.0). Die PHP Klasse setzt diese Struktur um.
Benutzung
Als Erstes muss ein neues Objekt mit den grundlegenden Informationen (Titel, URL, Beschreibung, Sprache) erstellt werden.
$feed = new FeedCreator("Feed Titel", "http://link/zum/feed", "Beschreibung des Feeds", "de-de");
Zusätzlich können noch weitere Feedinformationen hinzugefügt werden. Mehr in der API (ethalten im zip Archiv - Ordner doc).
Als nächstes werden dem Feed Artikel (Items) hinzugefügt. Das geht einfach über
$feed->addItem("Artikel Titel", "Text des Artikels", "Link zum vollständigem Artikel");
Die Länge des Textes wird standardmäßig nicht beschränkt. Die maximale Anzahl von Wörtern kann über
$feed->setSize(100);
angepasst werden (bevor sie addItem()
benutzen).Nun muss nur noch der RSS-Feed als XML-Datei ausgegeben werden. Das geht mit Hilfe der Funktion
$feed->getXML();
.Wichtig: Vor dem Aufruf dieser Methode darf noch nichts an den Browser gesendet worden sein. D. h. keine
print
oder echo
Ausgaben vorher.Erweiterungen
Den einzelnen Artikeln können noch mehr Informationen beigefügt werden.
Veröffentlichungsdatum
Nützlich für den Abonnementen für die Sortierung im Feedreader. Das Format richtet sich nach RFC 2822. Nützlich erweist sich die
date("r")
Funktion von PHP.addItem("Titel", "Text", "URL",
"Thu, 21 Dec 2000 16:01:07 +0200");
Autor
Der Autor des Artikels.
addItem("Titel", "Text", "URL", "Thu, 21 Dec 2000 16:01:07 +0200",
"autor@mail.de (Autor Name)");
Kategorie
Um dem Artikel eine Kategorie zuzuordnen, muss ein Hilfsobjekt (
Category
) erstellt werden. Diesem Objekt werden die Kategorien getrennt durch einen / und ein optionaler Namespace angegeben.$categorie = new Category("Technik/PC", "http://meinedomain.de");
addItem("Titel", "Text", "URL", "", "",
$category);
Anhang
Für einen Anhang gibt es auch eine Hilfsklasse (
Enclosure
). Diesem Objekt muss die URL des Anhangs, die Größe in Bytes und der MIME-Typ mitgeteilt werden.$enclosure = new Enclosure("http://image.png", 1536, "image/png");
addItem("Titel", "Text", "URL", "", "", null,
$enclosure);
Download
FeedCreator_0.3.zip
January 5, 2007
Persistenz für Desktop Anwendungen mit JPA und JavaDB
Voraussetzungen
In dieser Beschreibung benutze ich die Eclipse Entwicklungsumgebung und Hibernate als Implementierung der JPA. Es werden folgende Hibernate Komponenten benötigt: Hibernate Core, Hibernate Annotations und Hibernate EntityManager. Außerdem ist ein installiertes Java 6 erforderlich.
Aus den verschiedenen Hibernate Komponenten werden folgende Bibliotheken benötigt, die am besten in den Ordner
lib
kopiert werden.- lib
+ antlr-2.7.6.jar
+ asm-attrs.jar
+ asm.jar
+ c3p0-0.9.0.jar
+ cglib-2.1.3.jar
+ commons-collections-2.1.1.jar
+ commons-logging-1.0.4.jar
+ dom4j-1.6.1.jar
+ ejb3-persistence.jar
+ hibernate-annotations.jar
+ hibernate-entitymanager.jar
+ hibernate3.jar
+ javassist.jar
+ jboss-archive-browsing.jar
+ jta.jar
+ log4j-1.2.11.jar
Diese Bibliotheken müssen im Klassenpfad eingetragen sein. Außerdem ist es notwendig, die derby.jar
($JAVA_HOME/db/lib/
) ebenfalls in den Klassenpfad aufzunehmen.
Konfiguration
Trotz Verwendung von Annotations für das objektrelationale Mapping ist eine Konfiguration mittels XML Datei erforderlich. Für JPA wird dazu im Verzeichnis
etc/META-INF/
die Datei persistence.xml
angelegt. Darin wird angegeben, welche JPA Implementierung genutzt wird. Außerdem werden Persistenz Framework spezifische Einstellungen vorgenommen. Da diese Datei, ebenso wie die Jar-Dateien, im Klassenpfad verfügbar sein muss, wird das etc
Verzeichnis zu den Quellverzeichnissen (Source Folder) hinzugefügt.
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="hibernate">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="hibernate.connection.url" value="jdbc:derby:TestDatabase;create=true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
</properties>
</persistence-unit>
</persistence>
Jeder persistence-unit muss ein provider
zugeordnet werden. Außerdem können weitere Providerspezifische Eigenschaften definiert werden.
Für das Beispiel mit Hibernate müssen Eigenschaften der Verbindung eingetragen werden. So z.B. der verwendete JDBC Treiber (hibernate.connection.driver_class
) und die URL zur Datenbank (hibernate.connection.url
). Die mitgelieferte JavaDB kann über jdbc:derby:$database
erreicht werden. Beispielsweise wird durch die URL jdbc:derby:TestDatabase;create=true
die Datenbank TestDatabase benutzt. Sollte diese nicht existieren, wird sie angelegt. Das Hibernate auch mit der JavaDB arbeiten kann, muss zudem der zu verwendende Dialekt eingestellt werden.
Diese drei Einstellungen sind notwendig, um mit der Hibernate auf JavaDB zu arbeiten. Es können aber noch viel mehr Einstellungen für Hibernate vorgenommen werden (siehe Hibernate Konfiguration).
Verwendung
Nach der Erstellung der Konfiguration können nun Objekte dauerhaft gespeichert und wieder gelesen werden. Dazu müssen die zu persistierenden Beans (bzw. POJOs) mit Annotations versehen werden. Alle Klassen, die persistiert werden sollen, erhalten die Annotation
javax.persistence.Entity
.import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "PERSON_ID")
private long id;
@Column(name="DNAME")
private String name;
private String firstName;
public String getFirstName() {
return this.firtsName;
}
public void setFirstName(final String firstName) {
this.firstName = firstName;
}
public long getId() {
return this.id;
}
public void setId(final long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
}
Daneben ist es notwendig, dass die Bean ein Attribut besitzt, über die das Objekt eindeutig identifiziert werden kann. Im Normalfall ist dieses Attribut vom Typ
long
. Dieser Identifier muss mit einer entsprechenden Annotation markiert werden (javax.persistence.Id
). Weiterhin kann die Generierungsstrategie einer neuen Id festgelegt werden. Dazu wird die Annotation javax.persistence.GeneratedValue
benutzt.Neben der Deklaration der Id kann jeder Spalte der entsprechende Spaltenname in der Datenbank zugeordnet werden. Das geht über
javax.persistence.Colum
. Diese Annotation ist optional. Ist ein Attribut nicht damit versehen, wird einfach der Attributname als Spaltenname benutzt.Dies sind nur ein paar wenige Einstellungen für eine JavaBean. Für weiterführende Informationen kann die API zu Rate gezogen werden.
Objekt speichern
Die zentrale Klasse zum speichern und laden von Objekten ist
javax.persistence.EntityManager
. Eine Instanz kann über javax.persistence.EntityManagerFactory
erstellt werden.final EntityManagerFactory emf = Persistence.createEntityManagerFactory("hibernate");
final EntityManager em = emf.createEntityManager();
Nachdem der EntityManager
verfügbar ist, wird eine javax.persistence.EntityTransaction
benötigt. Diese Klasse ist zur Steuerung der Transaktionen verantwortlich. Will man ein Objekt in die Datenbank schreiben, braucht es eine offene Transaktion.
final EntityTransaction tx = em.getTransaction();
tx.begin();
Innerhalb dieser Transaktion kann nun ein Objekt persistiert werden.
final Person person = new Person();
person.setName("mrotzek");
person.setFirstName("michael");
em.persist(person);
Letztendlich muss die Transaktion noch geschlossen werden, um Änderungen wirklich in die Datenbank zu schreiben.
tx.commit();
em.close();
emf.close();
Objekt lesen
final EntityManagerFactory emf = Persistence.createEntityManagerFactory("hibernate");
final EntityManager em = emf.createEntityManager();
final EntityTransaction tx = em.getTransaction();
tx.begin();
final List persons = em.createQuery("select p from Person p").getResultList();
System.out.println(persons.size() + " person(s) found");
for (final Object p : persons) {
final Person lPerson = (Person) p;
System.out.println(lPerson .getName()+", "+lPerson .getFirstName()+" : "+lPerson .getId());
}
tx.commit();
em.close();
emf.close();
Referenzen
Java DB
Using Java DB in Desktop Applications
Working with Derby and Hibernate
Java Persistence with Hibernate
The Java Persistence API
Standardizing Java Persistence with the EJB3 Java Persistence API