diff --git a/P/Sda1/rdbms2catalogJpa/.gitignore b/P/Sda1/rdbms2catalogJpa/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..660be2a5fdb9e3019ef8fc737d47fba56fc32ff3 --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/.gitignore @@ -0,0 +1,5 @@ +.project +.classpath +/.settings/ +/target/ +A1.log \ No newline at end of file diff --git a/P/Sda1/rdbms2catalogJpa/Schema/catalog.xsd b/P/Sda1/rdbms2catalogJpa/Schema/catalog.xsd new file mode 100644 index 0000000000000000000000000000000000000000..9df8b8626a18dc60c23ccb69556e20c18c2da0cc --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/Schema/catalog.xsd @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> + + <xs:element name="catalog"> + <xs:complexType> + <xs:sequence> + <xs:element ref="product" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + <xs:key name="uniqueProductId"> + <xs:selector xpath="product"/> + <xs:field xpath="@id"/> + </xs:key> + </xs:element> + + <xs:element name="product"> + <xs:complexType> + <xs:sequence> + <xs:element name="name" type="xs:string"/> + <xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> + <xs:element name="age" type="xs:int" minOccurs="0" maxOccurs="1"/> + </xs:sequence> + <xs:attribute name="id" type="xs:int" use="required"/> + </xs:complexType> + </xs:element> + +</xs:schema> diff --git a/P/Sda1/rdbms2catalogJpa/Schema/schema.sql b/P/Sda1/rdbms2catalogJpa/Schema/schema.sql new file mode 100644 index 0000000000000000000000000000000000000000..f2dd345da36b4d32e9660d979ec1343528698bda --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/Schema/schema.sql @@ -0,0 +1,28 @@ +DROP TABLE IF EXISTS Description; +DROP TABLE IF EXISTS Product; + +CREATE TABLE Product ( + id INTEGER NOT NULL PRIMARY KEY + ,name VARCHAR(255) NOT NULL + ,age SMALLINT +) ENGINE=InnoDB; + +CREATE TABLE Description ( + product INTEGER NOT NULL + ,orderIndex int NOT NULL -- preserving the order of descriptions belonging to a given product + ,text VARCHAR(255) NOT NULL + ,UNIQUE(product, orderIndex) + ,FOREIGN KEY(product) REFERENCES Product(id) +) ENGINE=InnoDB; + +-- example data corresponding to products.xml -- + +-- Product lacking age property -- +INSERT INTO Product (id, name) VALUES ('mpt', 'Monkey Picked Tea'); +INSERT INTO Description VALUES('mpt', 0, 'Picked only by specially trained monkeys'); +INSERT INTO Description VALUES('mpt', 1, 'Rare wild Chinese tea'); + +INSERT INTO Product VALUES ('instantTent', '4-Person Instant Tent', 15); +INSERT INTO Description VALUES('instantTent', 0, 'Exclusive WeatherTec system.'); +INSERT INTO Description VALUES('instantTent', 1, '4-person, 1-room tent'); +INSERT INTO Description VALUES('instantTent', 2, 'Pre-attached tent poles'); diff --git a/P/Sda1/rdbms2catalogJpa/pom.xml b/P/Sda1/rdbms2catalogJpa/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..a1ce55b3d878a2f5f867b5db2f180547572b2a56 --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/pom.xml @@ -0,0 +1,65 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>de.hdm-stuttgart.mi</groupId> + <artifactId>lecturenotes-pom</artifactId> + <version>1.0</version> + + <relativePath>../../pom.xml</relativePath> + </parent> + + <groupId>de.hdm-stuttgart.mi.sda1</groupId> + <artifactId>rdbms2catalog</artifactId> + <version>2.0</version> + <packaging>jar</packaging> + + <name>rdbms2catalogJpa</name> + <url>http://www.mi.hdm-stuttgart.de/freedocs</url> + + <dependencies> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-entitymanager</artifactId> + <version>5.0.0.CR1</version> + </dependency> + + <dependency> + <groupId>org.hibernate.javax.persistence</groupId> + <artifactId>hibernate-jpa-2.1-api</artifactId> + <version>1.0.0.Final</version> + </dependency> + + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-c3p0</artifactId> + <version>5.0.0.CR1</version> + </dependency> + + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <version>2.1</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <version>2.1</version> + </dependency> + + <dependency> + <groupId>org.jdom</groupId> + <artifactId>jdom2</artifactId> + <version>2.0.5</version> + </dependency> + + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>5.1.34</version> + </dependency> + + </dependencies> + +</project> diff --git a/P/Sda1/rdbms2catalogJpa/products.xml b/P/Sda1/rdbms2catalogJpa/products.xml new file mode 100644 index 0000000000000000000000000000000000000000..15000ab5d08d5160a6b034cc6a2bcfacf66b9b9e --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/products.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<catalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="Schema/catalog.xsd"> + <product id="17"> + <name>Monkey Picked Tea</name> + <description>Rare wild Chinese tea</description> + <description>Picked only by specially trained monkeys</description> + </product> + <product id="42"> + <name>4-Person Instant Tent</name> + <description>4-person, 1-room tent</description> + <description>Pre-attached tent poles</description> + <description>Exclusive WeatherTec system.</description> + <age>15</age> + </product> +</catalog> \ No newline at end of file diff --git a/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java new file mode 100644 index 0000000000000000000000000000000000000000..f7879587615344dbd2eef926cfb7b55f4a0c451e --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Helper.java @@ -0,0 +1,18 @@ +package de.hdm_stuttgart.mi.sda1.sql2catalog; + +/** + * Project wide helper methods + * + */ +public class Helper { + /** + * Write message to stderr and exit with given error code + * @param errMsg + * @param errorCode + */ + public static void exitWithErrorMessage(final String errMsg, int errorCode) { + System.err.println(errMsg); + System.exit(errorCode); + } + +} diff --git a/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Messages.java b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Messages.java new file mode 100644 index 0000000000000000000000000000000000000000..781829729027fd9c1094d9365e0bb614180e2395 --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Messages.java @@ -0,0 +1,22 @@ +package de.hdm_stuttgart.mi.sda1.sql2catalog; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Messages { + private static final String BUNDLE_NAME = "de.hdm_stuttgart.mi.sda1.sql2catalog.messages"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + private Messages() { + } + + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java new file mode 100644 index 0000000000000000000000000000000000000000..052b0e9261c5ee81e9a27911cbe69214260cf149 --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/Rdbms2Xml.java @@ -0,0 +1,74 @@ +package de.hdm_stuttgart.mi.sda1.sql2catalog; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +import javax.xml.parsers.ParserConfigurationException; + +import org.jdom2.Element; +import org.jdom2.output.Format; +import org.jdom2.output.XMLOutputter; +import org.xml.sax.SAXException; + +/** + * A simple SAX parser demo + * + */ +public class Rdbms2Xml { + + /** + * @param args + * Unused + * @throws SAXException + * @throws ParserConfigurationException + * @throws IOException + */ + public static void main(String[] args) throws ParserConfigurationException, + SAXException, IOException { + + + + // Register Driver + final String sqlDriverClassName = Messages.getString("Xml2Rdbms.jdbcDriverName"); + try { + Class.forName(sqlDriverClassName); + } catch (ClassNotFoundException e) { + Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableRegisterDriverClass") + sqlDriverClassName + "'", 1); + } + + + // Opening a JDBC connection + // + Connection conn = null; + + final String jdbcConnectionUrl = Messages.getString("Xml2Rdbms.jdbcUrl"); + final String userName = Messages.getString("Xml2Rdbms.jdbcUser"); + try { + conn = DriverManager.getConnection(jdbcConnectionUrl, userName, Messages.getString("Xml2Rdbms.jdbcPasswd")); + } catch (SQLException e) { + Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableToConnect") + userName + "' to '" + + jdbcConnectionUrl + "'", 1); + } + + RdbmsAccess rdbmsAccess = null; + try { + rdbmsAccess = new RdbmsAccess(conn); + } catch (SQLException e) { + Helper.exitWithErrorMessage(Messages.getString("Xml2Rdbms.errMsgUnableInitDataInsert"), 1); + } + + final Element catalogElement = new Element("catalog"); + try { + rdbmsAccess.appendProducts(catalogElement); + } catch (SQLException e) { + Helper.exitWithErrorMessage("Unable to read database:" + e.getLocalizedMessage(), 1); + } + + // Write XML content to standard output + XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat()); + outputter.output(catalogElement, System.out); + } + +} diff --git a/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java new file mode 100644 index 0000000000000000000000000000000000000000..d13fc1070fc39906b9af984eb3be977bd7248bfd --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/RdbmsAccess.java @@ -0,0 +1,63 @@ +package de.hdm_stuttgart.mi.sda1.sql2catalog; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.jdom2.Element; + +/** + * Reading product data + * + */ +public class RdbmsAccess { + + final PreparedStatement selectProduct, selectDescription; + + /** + * @param conn Destination RDBMS + * @throws SQLException + */ + public RdbmsAccess(final Connection conn) throws SQLException { + conn.setAutoCommit(false); + selectProduct = conn.prepareStatement("SELECT * FROM Product"); + selectDescription = conn.prepareStatement("SELECT * FROM Description WHERE product = ? ORDER BY orderIndex"); + } + + public void appendProducts(final Element root) throws SQLException { + final ResultSet products = selectProduct.executeQuery(); + + while (products.next()) { + final int productId = products.getInt("id"); + final Element productElement = new Element("product"); + root.addContent(productElement); + productElement.setAttribute("id", "" + productId); + + final Element nameElement = new Element("name"); + productElement.addContent(nameElement); + nameElement.addContent(products.getString("name")); + + addDescriptions(productId, productElement); + + final int productAge = products.getInt("age"); + if (!products.wasNull()) { + final Element ageElement = new Element("age"); + productElement.addContent(ageElement); + ageElement.addContent("" + productAge); + } + } + products.close(); + } + + private void addDescriptions(final int productId, final Element productElement) throws SQLException { + selectDescription.setInt(1, productId); + final ResultSet descriptions = selectDescription.executeQuery(); + while (descriptions.next()) { + final Element descriptionElement = new Element("description"); + productElement.addContent(descriptionElement); + descriptionElement.addContent(descriptions.getString("text")); + } + descriptions.close(); + } +} diff --git a/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/messages.properties b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/messages.properties new file mode 100644 index 0000000000000000000000000000000000000000..a183dcc38baada85ed3f0fcafca90883ef3a940c --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/messages.properties @@ -0,0 +1,11 @@ +Xml2Rdbms.14=' +Xml2Rdbms.errMsgUnableCloseRdbms=Unable to close RDBMS access +Xml2Rdbms.errMsgUnableInitDataInsert=Unable to initialize data inserter +Xml2Rdbms.errMsgUnableRegisterDriverClass=Unable to register driver class ' +Xml2Rdbms.errMsgUnableToConnect=Unable to connect as user ' +Xml2Rdbms.jdbcDriverName=com.mysql.jdbc.Driver +Xml2Rdbms.jdbcPasswd=XYZ +Xml2Rdbms.jdbcUrl=jdbc:mysql://localhost:3306/hdm +Xml2Rdbms.jdbcUser=hdmuser +Xml2Rdbms.xmlSourceFileName=products.xml +Xml2Rdbms.errMsgUnableCommitTransaction=Unable to commit transaction \ No newline at end of file diff --git a/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/model/Description.java b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/model/Description.java new file mode 100644 index 0000000000000000000000000000000000000000..def55f16d5616d62f53de1b0455332826ae19d1c --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/model/Description.java @@ -0,0 +1,13 @@ +package de.hdm_stuttgart.mi.sda1.sql2catalog.model; + +import javax.persistence.Entity; + +@Entity +public class Description { + + + + + + +} diff --git a/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/model/Product.java b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/model/Product.java new file mode 100644 index 0000000000000000000000000000000000000000..dc7f3ff3266de065b969d99c330f57854a073428 --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/src/main/java/de/hdm_stuttgart/mi/sda1/sql2catalog/model/Product.java @@ -0,0 +1,25 @@ +package de.hdm_stuttgart.mi.sda1.sql2catalog.model; + +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +@Entity +public class Product { + + @Id + Integer id; + + @Column(nullable=false) + String name; + + int age; + + @OneToMany + List<Description> descriptions; + + +} diff --git a/P/Sda1/rdbms2catalogJpa/src/main/resources/META-INF/persistence.xml b/P/Sda1/rdbms2catalogJpa/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000000000000000000000000000000000..2e8b4a41c27055cc252c64480580fa1b736c0edf --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,32 @@ +<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence + http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd" + version="2.1"> + + <persistence-unit name="jpa-update" transaction-type="RESOURCE_LOCAL"> + <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> + + <properties> + <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/hdm" /> + <property name="javax.persistence.jdbc.user" value="hdmuser" /> + <property name="javax.persistence.jdbc.password" value="XYZ" /> + <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> + + <property name="hibernate.show_sql" value="true" /> + <property name="hibernate.format_sql" value="true" /> + <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" /> + <property name="hibernate.hbm2ddl.auto" value="update" /> + + <!-- Configuring Connection Pool --> + + <property name="hibernate.c3p0.min_size" value="5" /> + <property name="hibernate.c3p0.max_size" value="20" /> + <property name="hibernate.c3p0.timeout" value="500" /> + <property name="hibernate.c3p0.max_statements" value="50" /> + <property name="hibernate.c3p0.idle_test_period" value="2000" /> + + </properties> + </persistence-unit> + +</persistence> \ No newline at end of file diff --git a/P/Sda1/rdbms2catalogJpa/src/main/resources/log4j2.xml b/P/Sda1/rdbms2catalogJpa/src/main/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..eda4f3b0d781b09217fb4218285c39adf8d3c9c0 --- /dev/null +++ b/P/Sda1/rdbms2catalogJpa/src/main/resources/log4j2.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration> + <Appenders> + <File name="A1" fileName="A1.log" append="false"> + <PatternLayout pattern="%t %-5p %c{2} - %m%n"/> + </File> + <Console name="STDOUT" target="SYSTEM_OUT"> + <PatternLayout pattern="%C{2} (%F:%L) - %m%n"/> + </Console> + </Appenders> + <Loggers> + + <!-- You my want to define class or package level per-logger rules --> + <Logger name="de.hdm_stuttgart.mi.sda1.catalog2sax.App" level="debug"> + <AppenderRef ref="A1"/> + </Logger> + <Root level="debug"> + <AppenderRef ref="STDOUT"/> + </Root> + </Loggers> +</Configuration> \ No newline at end of file diff --git a/P/pom.xml b/P/pom.xml index bb52f2aed57d7c289e7e4679fac9976e5081d985..94da0f4b43c074e7f5d7653597d8e9f4733335b4 100644 --- a/P/pom.xml +++ b/P/pom.xml @@ -121,6 +121,7 @@ <module>Sda1/NoCast</module> <module>Sda1/rdbms2catalog</module> + <module>Sda1/rdbms2catalogJpa</module> <module>Sda1/VerifyImgAccess</module> <module>Sda1/xmlstatistics</module>