Initial webapp project for clojure scripting incubator
diff --git a/jpars.script.clojure/.classpath b/jpars.script.clojure/.classpath
new file mode 100644
index 0000000..2784a1b
--- /dev/null
+++ b/jpars.script.clojure/.classpath
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/jpars.script.clojure/.project b/jpars.script.clojure/.project
new file mode 100644
index 0000000..3eaec5d
--- /dev/null
+++ b/jpars.script.clojure/.project
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>jpars.script.clojure</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.wst.jsdt.core.jsNature</nature>
+ </natures>
+</projectDescription>
diff --git a/jpars.script.clojure/.settings/.jsdtscope b/jpars.script.clojure/.settings/.jsdtscope
new file mode 100644
index 0000000..b46b920
--- /dev/null
+++ b/jpars.script.clojure/.settings/.jsdtscope
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/main/webapp"/>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
+ <attributes>
+ <attribute name="hide" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
+ <classpathentry kind="output" path=""/>
+</classpath>
diff --git a/jpars.script.clojure/.settings/oracle.eclipse.tools.webtier.ui.prefs b/jpars.script.clojure/.settings/oracle.eclipse.tools.webtier.ui.prefs
new file mode 100644
index 0000000..b0107e5
--- /dev/null
+++ b/jpars.script.clojure/.settings/oracle.eclipse.tools.webtier.ui.prefs
@@ -0,0 +1,5 @@
+_hiddenCategory_\:HTML=false
+_hiddenCategory_\:ManagedBeans=false
+_hiddenCategory_\:PageVariables=false
+_hiddenCategory_\:jsp11=false
+eclipse.preferences.version=1
diff --git a/jpars.script.clojure/.settings/org.eclipse.jdt.core.prefs b/jpars.script.clojure/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..45a6e0e
--- /dev/null
+++ b/jpars.script.clojure/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/jpars.script.clojure/.settings/org.eclipse.m2e.core.prefs b/jpars.script.clojure/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/jpars.script.clojure/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/jpars.script.clojure/.settings/org.eclipse.wst.common.component b/jpars.script.clojure/.settings/org.eclipse.wst.common.component
new file mode 100644
index 0000000..469a63c
--- /dev/null
+++ b/jpars.script.clojure/.settings/org.eclipse.wst.common.component
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
+ <wb-module deploy-name="jpars.script.clojure">
+ <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
+ <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
+ <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
+ <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
+ <property name="context-root" value="jpars.script.clojure"/>
+ <property name="java-output-path" value="/jpars.script.clojure/target/classes"/>
+ </wb-module>
+</project-modules>
diff --git a/jpars.script.clojure/.settings/org.eclipse.wst.common.project.facet.core.xml b/jpars.script.clojure/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 0000000..d74c55e
--- /dev/null
+++ b/jpars.script.clojure/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <fixed facet="wst.jsdt.web"/>
+ <installed facet="java" version="1.5"/>
+ <installed facet="jst.web" version="2.3"/>
+ <installed facet="wst.jsdt.web" version="1.0"/>
+</faceted-project>
diff --git a/jpars.script.clojure/.settings/org.eclipse.wst.jsdt.ui.superType.container b/jpars.script.clojure/.settings/org.eclipse.wst.jsdt.ui.superType.container
new file mode 100644
index 0000000..3bd5d0a
--- /dev/null
+++ b/jpars.script.clojure/.settings/org.eclipse.wst.jsdt.ui.superType.container
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/jpars.script.clojure/.settings/org.eclipse.wst.jsdt.ui.superType.name b/jpars.script.clojure/.settings/org.eclipse.wst.jsdt.ui.superType.name
new file mode 100644
index 0000000..05bd71b
--- /dev/null
+++ b/jpars.script.clojure/.settings/org.eclipse.wst.jsdt.ui.superType.name
@@ -0,0 +1 @@
+Window
\ No newline at end of file
diff --git a/jpars.script.clojure/pom.xml b/jpars.script.clojure/pom.xml
new file mode 100644
index 0000000..ba9cb8a
--- /dev/null
+++ b/jpars.script.clojure/pom.xml
@@ -0,0 +1,39 @@
+<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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.eclipse.persistence.incubator</groupId>
+ <artifactId>jpars.script.clojure</artifactId>
+ <packaging>war</packaging>
+ <version>2.4.2-SNAPSHOT</version>
+ <name>jpars.script.clojure Maven Webapp</name>
+ <url>http://maven.apache.org</url>
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.oracle.toplink</groupId>
+ <artifactId>toplink-dataservices-web</artifactId>
+ <version>12.1.2-0-0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.oracle.toplink</groupId>
+ <artifactId>eclipselink</artifactId>
+ <version>12.1.2-0-0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.oracle.toplink</groupId>
+ <artifactId>javax.persistence</artifactId>
+ <version>12.1.2-0-0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <finalName>jpars.script.clojure</finalName>
+ </build>
+</project>
diff --git a/jpars.script.clojure/src/main/java/example/EmployeeDynamicMappings.java b/jpars.script.clojure/src/main/java/example/EmployeeDynamicMappings.java
new file mode 100644
index 0000000..6cb7203
--- /dev/null
+++ b/jpars.script.clojure/src/main/java/example/EmployeeDynamicMappings.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 1198, 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * dclarke - Dynamic Persistence INCUBATION - Enhancement 200045
+ * http://wiki.eclipse.org/EclipseLink/Development/JPA/Dynamic
+ *
+ * This code is being developed under INCUBATION and is not currently included
+ * in the automated EclipseLink build. The API in this code may change, or
+ * may never be included in the product. Please provide feedback through mailing
+ * lists or the bug database.
+ ******************************************************************************/
+package example;
+
+import org.eclipse.persistence.dynamic.DynamicClassLoader;
+import org.eclipse.persistence.dynamic.DynamicType;
+import org.eclipse.persistence.jpa.dynamic.JPADynamicTypeBuilder;
+import org.eclipse.persistence.mappings.OneToManyMapping;
+import org.eclipse.persistence.mappings.OneToOneMapping;
+
+/**
+ * Example of creating mappings in API
+ *
+ * @author dclarke
+ */
+public class EmployeeDynamicMappings {
+
+ /**
+ * Configure using dynamic API.
+ */
+ private static void configureAddress(JPADynamicTypeBuilder address) {
+ address.setPrimaryKeyFields("ADDR_ID");
+
+ address.addDirectMapping("id", int.class, "ADDR_ID");
+ address.addDirectMapping("street", String.class, "STREET");
+ address.addDirectMapping("city", String.class, "CITY");
+ address.addDirectMapping("province", String.class, "PROV");
+ address.addDirectMapping("postalCode", String.class, "P_CODE");
+ address.addDirectMapping("country", String.class, "COUNTRY");
+
+ address.configureSequencing("ADDR_SEQ", "ADDR_ID");
+ }
+
+ /**
+ * Configure using dynamic API.
+ */
+ private static void configureEmployee(JPADynamicTypeBuilder employee, JPADynamicTypeBuilder address, JPADynamicTypeBuilder phone) {
+ employee.setPrimaryKeyFields("EMP_ID");
+
+ employee.addDirectMapping("id", int.class, "D_EMPLOYEE.EMP_ID");
+ employee.addDirectMapping("firstName", String.class, "D_EMPLOYEE.F_NAME");
+ employee.addDirectMapping("lastName", String.class, "D_EMPLOYEE.L_NAME");
+ employee.addDirectMapping("gender", String.class, "D_EMPLOYEE.GENDER");
+ employee.addDirectMapping("salary", int.class, "D_SALARY.SALARY");
+
+ OneToOneMapping addressMapping = employee.addOneToOneMapping("address", address.getType(), "ADDR_ID");
+ addressMapping.setCascadeAll(true);
+ addressMapping.setIsPrivateOwned(true);
+
+ employee.addOneToOneMapping("manager", employee.getType(), "MANAGER_ID");
+
+ OneToManyMapping phoneMapping = employee.addOneToManyMapping("phoneNumbers", phone.getType(), "OWNER_ID");
+ phoneMapping.setCascadeAll(true);
+ phoneMapping.setIsPrivateOwned(true);
+
+ employee.addOneToManyMapping("managedEmployees", employee.getType(), "MANAGER_ID");
+
+ employee.addDirectCollectionMapping("responsibilities", "D_RESPONS", "RESPON_DESC", String.class, "EMP_ID");
+
+ employee.configureSequencing("EMP_SEQ", "EMP_ID");
+ }
+
+ /**
+ * Configure using dynamic API.
+ */
+ private static void configurePhone(JPADynamicTypeBuilder phone, JPADynamicTypeBuilder employee) {
+ phone.setPrimaryKeyFields("PHONE_TYPE", "EMP_ID");
+
+ phone.addDirectMapping("type", String.class, "PHONE_TYPE");
+ phone.addDirectMapping("ownerId", int.class, "EMP_ID").readOnly();
+ phone.addDirectMapping("areaCode", String.class, "AREA_CODE");
+ phone.addDirectMapping("number", String.class, "PNUMBER");
+
+ phone.addOneToOneMapping("owner", employee.getType(), "EMP_ID");
+ }
+
+
+ /**
+ * Create the types using the dynamic API.
+ */
+ public static DynamicType[] createTypes(DynamicClassLoader dcl, String packageName) {
+ String packagePrefix = packageName.endsWith(".") ? packageName : packageName + ".";
+
+ Class<?> employeeClass = dcl.createDynamicClass(packagePrefix + "Employee");
+ Class<?> addressClass = dcl.createDynamicClass(packagePrefix + "Address");
+ Class<?> phoneClass = dcl.createDynamicClass(packagePrefix + "PhoneNumber");
+
+ JPADynamicTypeBuilder employee = new JPADynamicTypeBuilder(employeeClass, null, "D_EMPLOYEE", "D_SALARY");
+ JPADynamicTypeBuilder address = new JPADynamicTypeBuilder(addressClass, null, "D_ADDRESS");
+ JPADynamicTypeBuilder phone = new JPADynamicTypeBuilder(phoneClass, null, "D_PHONE");
+
+ configureAddress(address);
+ configureEmployee(employee, address, phone);
+ configurePhone(phone, employee);
+
+ DynamicType[] types = new DynamicType[] { employee.getType(), address.getType(), phone.getType() };
+ return types;
+ }
+}
diff --git a/jpars.script.clojure/src/main/java/example/PersistenceHelper.java b/jpars.script.clojure/src/main/java/example/PersistenceHelper.java
new file mode 100644
index 0000000..f549b5b
--- /dev/null
+++ b/jpars.script.clojure/src/main/java/example/PersistenceHelper.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * dclarke - example
+ ******************************************************************************/
+package example;
+
+import static org.eclipse.persistence.jaxb.MarshallerProperties.MEDIA_TYPE;
+import static org.eclipse.persistence.jaxb.UnmarshallerProperties.JSON_INCLUDE_ROOT;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+import org.eclipse.persistence.dynamic.DynamicClassLoader;
+import org.eclipse.persistence.internal.queries.ReportItem;
+import org.eclipse.persistence.jaxb.JAXBContextFactory;
+import org.eclipse.persistence.oxm.MediaType;
+import org.eclipse.persistence.queries.ConstructorReportItem;
+import org.eclipse.persistence.queries.DatabaseQuery;
+import org.eclipse.persistence.queries.ReportQuery;
+import org.eclipse.persistence.sessions.server.Server;
+
+/**
+ * Simple helper responsible for creation of JPA and MOXy contexts.
+ *
+ * @author dclarke
+ */
+public class PersistenceHelper {
+
+ public static final String EMPLOYEE_XML_PU = "employee-xml";
+
+ public static final String EMPLOYEE_API_PU = "employee-api";
+
+ public static EntityManagerFactory createEntityManagerFactory(DynamicClassLoader dcl, String persistenceUnit, boolean createTables) {
+ Map<String, Object> props = new HashMap<String, Object>();
+
+ // Ensure the persistence.xml provided data source are ignored for Java
+ // SE testing
+ props.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, "");
+ props.put(PersistenceUnitProperties.JTA_DATASOURCE, "");
+
+ if (createTables) {
+ props.put(PersistenceUnitProperties.DDL_GENERATION, PersistenceUnitProperties.DROP_AND_CREATE);
+ props.put(PersistenceUnitProperties.DDL_GENERATION_MODE, PersistenceUnitProperties.DDL_DATABASE_GENERATION);
+ }
+
+ // Configure the use of embedded derby for the tests allowing system
+ // properties of the same name to override
+ props.put(PersistenceUnitProperties.JDBC_DRIVER, "org.apache.derby.jdbc.EmbeddedDriver");
+ props.put(PersistenceUnitProperties.JDBC_URL, "jdbc:derby:target/derby/mysports;create=true");
+ props.put(PersistenceUnitProperties.JDBC_USER, "app");
+ props.put(PersistenceUnitProperties.JDBC_PASSWORD, "app");
+ props.put(PersistenceUnitProperties.CLASSLOADER, dcl);
+ props.put(PersistenceUnitProperties.WEAVING, "static");
+ return Persistence.createEntityManagerFactory(persistenceUnit, props);
+ }
+
+ private static JAXBContext context;
+
+ public static JAXBContext getContext(EntityManager em) throws JAXBException {
+ if (context == null) {
+ Set<Class<?>> classes = new HashSet<Class<?>>();
+
+ Server serverSession = em.unwrap(Server.class);
+
+ for (List<DatabaseQuery> queryList : serverSession.getQueries().values()) {
+ for (DatabaseQuery query : queryList) {
+ if (query.isReportQuery()) {
+ ReportQuery rq = (ReportQuery) query;
+ for (ReportItem item : rq.getItems()) {
+ if (item.isConstructorItem()) {
+ classes.add(((ConstructorReportItem) item).getResultType());
+ }
+ }
+ }
+ }
+ }
+
+ context = JAXBContextFactory.createContext(classes.toArray(new Class[classes.size()]), null);
+ }
+ return context;
+ }
+
+ public static Marshaller createMarshaller(EntityManager em, MediaType mediaType) throws JAXBException {
+ Marshaller marshaller = getContext(em).createMarshaller();
+ marshaller.setProperty(MEDIA_TYPE, mediaType.getMediaType());
+ return marshaller;
+ }
+
+ public static Unmarshaller createUnmarshaller(EntityManager em, MediaType mediaType) throws JAXBException {
+ Unmarshaller unmarshaller = getContext(em).createUnmarshaller();
+ unmarshaller.setProperty(MEDIA_TYPE, mediaType.getMediaType());
+ unmarshaller.setProperty(JSON_INCLUDE_ROOT, false);
+ return unmarshaller;
+ }
+
+}
diff --git a/jpars.script.clojure/src/main/java/example/Queries.java b/jpars.script.clojure/src/main/java/example/Queries.java
new file mode 100644
index 0000000..eb2e84d
--- /dev/null
+++ b/jpars.script.clojure/src/main/java/example/Queries.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 1198, 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * dclarke - Dynamic Persistence INCUBATION - Enhancement 200045
+ * http://wiki.eclipse.org/EclipseLink/Development/JPA/Dynamic
+ *
+ * This code is being developed under INCUBATION and is not currently included
+ * in the automated EclipseLink build. The API in this code may change, or
+ * may never be included in the product. Please provide feedback through mailing
+ * lists or the bug database.
+ ******************************************************************************/
+package example;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import org.eclipse.persistence.config.QueryHints;
+import org.eclipse.persistence.descriptors.ClassDescriptor;
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.dynamic.DynamicType;
+import org.eclipse.persistence.expressions.ExpressionBuilder;
+import org.eclipse.persistence.jpa.JpaHelper;
+import org.eclipse.persistence.oxm.MediaType;
+import org.eclipse.persistence.queries.ReadAllQuery;
+
+/**
+ * Simple query examples for the XML mapped Employee domain model.
+ *
+ * @author dclarke
+ * @since EclipseLink - Dynamic Incubator (1.1.0-branch)
+ */
+public class Queries {
+
+ public DynamicEntity findEmployee(EntityManager em, DynamicType type, Object id) {
+ return (DynamicEntity) em.find(type.getJavaClass(), id);
+ }
+
+ /**
+ * Simple example using dynamic JP QL to retrieve all Employee instances
+ * sorted by lastName and firstName.
+ */
+ @SuppressWarnings("unchecked")
+ public List<DynamicEntity> readAllEmployeesUsing(EntityManager em) {
+ return em.createQuery("SELECT e FROM Employee e ORDER BY e.id ASC").getResultList();
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<DynamicEntity> joinFetchEmployeeWithAddress(EntityManager em) {
+ return em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address ORDER BY e.lastName ASC, e.firstName ASC").getResultList();
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<DynamicEntity> joinFetchHint(EntityManager em) {
+ Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager.address.city = 'Ottawa' ORDER BY e.lastName ASC, e.firstName ASC");
+ query.setHint(QueryHints.FETCH, "e.address");
+ query.setHint(QueryHints.FETCH, "e.manager");
+ query.setHint(QueryHints.FETCH, "e.manager.address");
+ query.setHint(QueryHints.BATCH, "e.manager.phoneNumbers");
+ List<DynamicEntity> emps = query.getResultList();
+
+ for (DynamicEntity emp : emps) {
+ emp.<DynamicEntity>get("manager").<Collection<DynamicEntity>>get("phoneNumbers").size();
+ }
+
+ return emps;
+ }
+
+ public int minimumEmployeeId(EntityManager em) {
+ return ((Number) em.createQuery("SELECT MIN(e.id) FROM Employee e").getSingleResult()).intValue();
+ }
+
+ public DynamicEntity minimumEmployee(EntityManager em) {
+ Query q = em.createQuery("SELECT e FROM Employee e WHERE e.id in (SELECT MIN(ee.id) FROM Employee ee)");
+
+ return (DynamicEntity) q.getSingleResult();
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<DynamicEntity> findEmployeesUsingGenderIn(EntityManager em) {
+ return em.createQuery("SELECT e FROM Employee e WHERE e.gender IN (:GENDER1, :GENDER2)").setParameter("GENDER1", "Male").setParameter("GENDER2", "Female").getResultList();
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<DynamicEntity> findUsingNativeReadAllQuery(EntityManager em) {
+ ClassDescriptor descriptor = JpaHelper.getEntityManager(em).getServerSession().getDescriptorForAlias("Employee");
+ ReadAllQuery raq = new ReadAllQuery(descriptor.getJavaClass());
+ ExpressionBuilder eb = raq.getExpressionBuilder();
+ raq.setSelectionCriteria(eb.get("gender").equal("Male"));
+
+ Query query = JpaHelper.createQuery(raq, em);
+
+ return query.getResultList();
+ }
+
+ public DynamicEntity minEmployeeWithAddressAndPhones(EntityManager em) {
+ return (DynamicEntity) em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT MIN(p.id) FROM PhoneNumber p)").getSingleResult();
+ }
+
+ public List<?> findEmployeeSummaries(EntityManager em) throws JAXBException {
+ List<?> results = em.createNamedQuery("Employee.findSummary").getResultList();
+ Marshaller marshaller = PersistenceHelper.createMarshaller(em, MediaType.APPLICATION_JSON);
+
+ for (Object result: results) {
+ marshaller.marshal(result, System.out);
+ }
+
+ return results;
+ }
+}
diff --git a/jpars.script.clojure/src/main/java/example/Samples.java b/jpars.script.clojure/src/main/java/example/Samples.java
new file mode 100644
index 0000000..44e352d
--- /dev/null
+++ b/jpars.script.clojure/src/main/java/example/Samples.java
@@ -0,0 +1,509 @@
+/*******************************************************************************
+ * Copyright (c) 1198, 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * dclarke - Dynamic Persistence INCUBATION - Enhancement 200045
+ * http://wiki.eclipse.org/EclipseLink/Development/JPA/Dynamic
+ *
+ * This code is being developed under INCUBATION and is not currently included
+ * in the automated EclipseLink build. The API in this code may change, or
+ * may never be included in the product. Please provide feedback through mailing
+ * lists or the bug database.
+ ******************************************************************************/
+package example;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Query;
+
+import junit.framework.Assert;
+
+import org.eclipse.persistence.descriptors.ClassDescriptor;
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.expressions.ExpressionBuilder;
+import org.eclipse.persistence.jpa.JpaHelper;
+import org.eclipse.persistence.queries.DeleteAllQuery;
+import org.eclipse.persistence.queries.ReportQuery;
+
+/**
+ *
+ * @author dclarke
+ * @since EclipseLink - Dynamic Incubator (1.1.0-branch)
+ */
+public class Samples {
+ private EntityManagerFactory emf;
+ public DynamicEntity[] employees;
+
+ public Samples(EntityManagerFactory emf) {
+ this.emf = emf;
+
+ this.employees = new DynamicEntity[] { basicEmployeeExample1(), basicEmployeeExample2(), basicEmployeeExample3(), basicEmployeeExample4(), basicEmployeeExample5(), basicEmployeeExample6(), basicEmployeeExample7(), basicEmployeeExample8(), basicEmployeeExample9(), basicEmployeeExample10(), basicEmployeeExample11(), basicEmployeeExample12() };
+
+ // Setup management hierarchy
+ addManagedEmployees(0, new int[] { 2, 3, 4 });
+ addManagedEmployees(1, new int[] { 5, 0 });
+ addManagedEmployees(2, new int[] {});
+ addManagedEmployees(3, new int[] {});
+ addManagedEmployees(4, new int[] {});
+ addManagedEmployees(5, new int[] {});
+ addManagedEmployees(6, new int[] {});
+ addManagedEmployees(7, new int[] {});
+ addManagedEmployees(8, new int[] {});
+ addManagedEmployees(9, new int[] { 7, 8, 10, 11 });
+ addManagedEmployees(10, new int[] { 6 });
+ addManagedEmployees(11, new int[] { 1 });
+ }
+
+ private DynamicEntity newInstance(String entityAlias) {
+ ClassDescriptor descriptor = JpaHelper.getServerSession(this.emf).getDescriptorForAlias(entityAlias);
+ return (DynamicEntity) descriptor.getInstantiationPolicy().buildNewInstance();
+ }
+
+ private Class<?> getDynamicClass(String entityAlias) {
+ ClassDescriptor descriptor = JpaHelper.getServerSession(this.emf).getDescriptorForAlias(entityAlias);
+ return descriptor.getJavaClass();
+ }
+
+ private DynamicEntity addPhoneNumber(DynamicEntity employee, String type, String areaCode, String number) {
+ DynamicEntity phone = newInstance("PhoneNumber");
+ phone.set("type", type);
+ phone.set("areaCode", areaCode);
+ phone.set("number", number);
+ phone.set("owner", employee);
+ employee.<Collection<DynamicEntity>> get("phoneNumbers").add(phone);
+ return phone;
+ }
+
+ public DynamicEntity basicEmployeeExample1() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Bob");
+ employee.set("lastName", "Smith");
+ employee.set("gender", "Male");
+ employee.set("salary", 35000);
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Toronto");
+ address.set("postalCode", "L5J2B5");
+ address.set("province", "ONT");
+ address.set("street", "1450 Acme Cr., Suite 4");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ employee.<Collection<String>> get("responsibilities").add("Water the office plants.");
+ employee.<Collection<String>> get("responsibilities").add("Maintain the kitchen facilities.");
+ addPhoneNumber(employee, "Work", "613", "5558812");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample10() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Jill");
+ employee.set("lastName", "May");
+ employee.set("gender", "Female");
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Calgary");
+ address.set("postalCode", "J5J2B5");
+ address.set("province", "AB");
+ address.set("street", "1111 Mooseland Rd.");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ employee.set("salary", 56232);
+ addPhoneNumber(employee, "Work", "613", "5558812");
+ addPhoneNumber(employee, "Work Fax", "613", "5555943");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample11() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Sarah-Lou");
+ employee.set("lastName", "Smitty");
+ employee.set("gender", "Female");
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Arnprior");
+ address.set("postalCode", "W1A2B5");
+ address.set("province", "ONT");
+ address.set("street", "1 Hawthorne Drive");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ employee.set("salary", 75000);
+ addPhoneNumber(employee, "Work Fax", "613", "5555943");
+ addPhoneNumber(employee, "Home", "613", "5551234");
+ addPhoneNumber(employee, "Cellular", "416", "5551111");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample12() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Jim-Bob");
+ employee.set("lastName", "Jefferson");
+ employee.set("gender", "Male");
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Yellowknife");
+ address.set("postalCode", "Y5J2N5");
+ address.set("province", "YK");
+ address.set("street", "1112 Gold Rush Rd.");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ employee.set("salary", 50000);
+ addPhoneNumber(employee, "Home", "613", "5551234");
+ addPhoneNumber(employee, "Cellular", "416", "5551111");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample2() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "John");
+ employee.set("lastName", "Way");
+ employee.set("gender", "Male");
+ employee.set("salary", 53000);
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Ottawa");
+ address.set("postalCode", "K5J2B5");
+ address.set("province", "ONT");
+ address.set("street", "12 Merivale Rd., Suite 5");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ employee.<Collection<String>> get("responsibilities").add("Hire people when more people are required.");
+ employee.<Collection<String>> get("responsibilities").add("Lay off employees when less people are required.");
+ addPhoneNumber(employee, "Work", "613", "5558812");
+ addPhoneNumber(employee, "ISDN", "905", "5553691");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample3() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Charles");
+ employee.set("lastName", "Chanley");
+ employee.set("gender", "Male");
+ employee.set("salary", 43000);
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Montreal");
+ address.set("postalCode", "Q2S5Z5");
+ address.set("province", "QUE");
+ address.set("street", "1 Canadien Place");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ employee.<Collection<String>> get("responsibilities").add("Perform code reviews as required.");
+
+ addPhoneNumber(employee, "Pager", "976", "5556666");
+ addPhoneNumber(employee, "ISDN", "905", "5553691");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample4() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Emanual");
+ employee.set("lastName", "Smith");
+ employee.set("gender", "Male");
+ employee.set("salary", 49631);
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Vancouver");
+ address.set("postalCode", "N5J2N5");
+ address.set("province", "BC");
+ address.set("street", "20 Mountain Blvd., Floor 53, Suite 6");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ employee.<Collection<String>> get("responsibilities").add("Have to fix the Database problem.");
+ addPhoneNumber(employee, "Work Fax", "613", "5555943");
+ addPhoneNumber(employee, "Cellular", "416", "5551111");
+ addPhoneNumber(employee, "Pager", "976", "5556666");
+ addPhoneNumber(employee, "ISDN", "905", "5553691");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample5() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Sarah");
+ employee.set("lastName", "Way");
+ employee.set("gender", "Female");
+ employee.set("salary", 87000);
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Prince Rupert");
+ address.set("postalCode", "K3K5D5");
+ address.set("province", "BC");
+ address.set("street", "3254 Parkway Place");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ employee.<Collection<String>> get("responsibilities").add("Write code documentation.");
+ addPhoneNumber(employee, "Work", "613", "5558812");
+ addPhoneNumber(employee, "ISDN", "905", "5553691");
+ addPhoneNumber(employee, "Home", "613", "5551234");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample6() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Marcus");
+ employee.set("lastName", "Saunders");
+ employee.set("gender", "Male");
+ employee.set("salary", 54300);
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Perth");
+ address.set("postalCode", "Y3Q2N9");
+ address.set("province", "ONT");
+ address.set("street", "234 Caledonia Lane");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ employee.<Collection<String>> get("responsibilities").add("Write user specifications.");
+ addPhoneNumber(employee, "ISDN", "905", "5553691");
+ addPhoneNumber(employee, "Work", "613", "5558812");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample7() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Nancy");
+ employee.set("lastName", "White");
+ employee.set("gender", "Female");
+ employee.set("salary", 31000);
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Metcalfe");
+ address.set("postalCode", "Y4F7V6");
+ address.set("province", "ONT");
+ address.set("street", "2 Anderson Rd.");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ addPhoneNumber(employee, "Home", "613", "5551234");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample8() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Fred");
+ employee.set("lastName", "Jones");
+ employee.set("gender", "Male");
+ employee.set("salary", 500000);
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Victoria");
+ address.set("postalCode", "Z5J2N5");
+ address.set("province", "BC");
+ address.set("street", "382 Hyde Park Blvd.");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ addPhoneNumber(employee, "Cellular", "416", "5551111");
+ addPhoneNumber(employee, "ISDN", "905", "5553691");
+
+ return employee;
+ }
+
+ public DynamicEntity basicEmployeeExample9() {
+ DynamicEntity employee = newInstance("Employee");
+
+ employee.set("firstName", "Betty");
+ employee.set("lastName", "Jones");
+ employee.set("gender", "Female");
+ employee.set("salary", 500001);
+
+ DynamicEntity address = newInstance("Address");
+ address.set("city", "Smith Falls");
+ address.set("postalCode", "C6C6C6");
+ address.set("province", "ONT");
+ address.set("street", "89 Chocolate Drive");
+ address.set("country", "Canada");
+ employee.set("address", address);
+
+ addPhoneNumber(employee, "Work", "613", "5558812");
+ addPhoneNumber(employee, "ISDN", "905", "5553691");
+
+ return employee;
+ }
+
+ private void addManagedEmployees(int managerIndex, int[] employeeIndeces) {
+ DynamicEntity manager = this.employees[managerIndex];
+
+ if (manager.<Collection<DynamicEntity>> get("managedEmployees").isEmpty()) {
+ for (int index = 0; index < employeeIndeces.length; index++) {
+ manager.<Collection<DynamicEntity>> get("managedEmployees").add(this.employees[employeeIndeces[index]]);
+ }
+ }
+ }
+
+ /**
+ * Register all of the population in the provided EntityManager to be
+ * persisted This method should only be called from within a test case. It
+ * asserts that the provided EntityManager is in a transaction and that the
+ * database tables are empty.
+ */
+ public void persistAll(EntityManager em) {
+ Assert.assertTrue("EntityManager not in Transaction", em.getTransaction().isActive());
+
+ // Verify that the database tables are empty
+ assertCount(em, "Employee", 0);
+ assertCount(em, "Address", 0);
+ assertCount(em, "PhoneNumber", 0);
+
+ for (int index = 0; index < this.employees.length; index++) {
+ em.persist(this.employees[index]);
+ }
+
+ em.flush();
+ verifyCounts(em);
+ }
+
+ public void verifyCounts(EntityManager em) {
+ assertCount(em, "Employee", this.employees.length);
+ assertCount(em, "Address", this.employees.length);
+ }
+
+ /**
+ * Verify that the provided entity type has no rows in the database using a
+ * native ReportQuery.
+ *
+ * @param entityClass
+ * @param count
+ */
+ public void assertCount(EntityManager em, String entityAlias, int count) {
+ Class<?> entityClass = getDynamicClass(entityAlias);
+ ReportQuery query = new ReportQuery(entityClass, new ExpressionBuilder());
+ query.addCount();
+ query.setShouldReturnSingleValue(true);
+
+ int dbCount = ((Number) JpaHelper.getEntityManager(em).getUnitOfWork().executeQuery(query)).intValue();
+ Assert.assertEquals("Incorrect quantity found of " + entityClass, count, dbCount);
+ }
+
+ /**
+ * Verify that the provided list of Employee instances matches the sample
+ * population.
+ *
+ * @param employees
+ */
+ public void assertSame(List<DynamicEntity> dbEmps) {
+ Assert.assertEquals("Incorrect quantity of employees", this.employees.length, dbEmps.size());
+ Collections.sort(dbEmps, new DynamicEntityComparator());
+
+ List<DynamicEntity> sampleEmps = new ArrayList<DynamicEntity>();
+ for (int index = 0; index < this.employees.length; index++) {
+ sampleEmps.add(this.employees[index]);
+ }
+ Collections.sort(sampleEmps, new DynamicEntityComparator());
+
+ for (int index = 0; index < this.employees.length; index++) {
+ DynamicEntity emp = sampleEmps.get(index);
+ DynamicEntity dbEmp = dbEmps.get(index);
+
+ Assert.assertEquals("First name does not match on employees[" + index + "]", emp.<String> get("firstName"), dbEmp.<String> get("firstName"));
+ Assert.assertEquals("Last name does not match on employees[" + index + "]", emp.<String> get("lastName"), dbEmp.<String> get("lastName"));
+ Assert.assertEquals("Salary does not match on employees[" + index + "]", emp.<Integer> get("salary"), dbEmp.<Integer> get("salary"));
+ }
+ }
+
+ /**
+ * Simple comparator used to order the employees for use within assertSame
+ */
+ class DynamicEntityComparator implements Comparator<DynamicEntity> {
+
+ public int compare(DynamicEntity emp1, DynamicEntity emp2) {
+ return emp1.<Integer> get("id") - emp2.<Integer> get("id");
+ }
+
+ }
+
+ /**
+ * Extract the id's from the sample Employee instances.
+ *
+ * @param em
+ * @return
+ */
+ public int[] getEmployeeIds(EntityManager em) {
+ int[] ids = new int[this.employees.length];
+
+ for (int index = 0; index < this.employees.length; index++) {
+ ids[index] = this.employees[index].<Integer> get("id");
+ }
+
+ return ids;
+ }
+
+ /**
+ * Reset the database so that only the sample population exists.
+ *
+ * @param em
+ */
+ public void resetDatabase(EntityManager em) {
+ em.getTransaction().begin();
+
+ DeleteAllQuery deleteEmpsQuery = new DeleteAllQuery(getDynamicClass("Employee"));
+ ExpressionBuilder eb = deleteEmpsQuery.getExpressionBuilder();
+ deleteEmpsQuery.setSelectionCriteria(eb.get("id").notIn(getEmployeeIds(em)));
+ deleteEmpsQuery.setFlushOnExecute(true);
+
+ JpaHelper.getEntityManager(em).getUnitOfWork().executeQuery(deleteEmpsQuery);
+
+ em.getTransaction().commit();
+ }
+
+ public void resetSalary(EntityManager em) {
+ boolean startedTX = !em.getTransaction().isActive();
+
+ if (startedTX) {
+ em.getTransaction().begin();
+ }
+
+ for (int index = 0; index < this.employees.length; index++) {
+ DynamicEntity emp = this.employees[index];
+ Query query = em.createQuery("SELECT e FROM Employee e WHERE e.firstName = :FNAME AND e.lastName = :LNAME");
+ query.setParameter("FNAME", emp.<String> get("firstName"));
+ query.setParameter("LNAME", emp.<String> get("lastName"));
+
+ DynamicEntity dbEmp = (DynamicEntity) query.getSingleResult();
+ dbEmp.set("salary", this.employees[index].<Integer> get("salary"));
+ }
+
+ if (startedTX) {
+ em.getTransaction().commit();
+ }
+ }
+}
diff --git a/jpars.script.clojure/src/main/java/example/Transactions.java b/jpars.script.clojure/src/main/java/example/Transactions.java
new file mode 100644
index 0000000..8154258
--- /dev/null
+++ b/jpars.script.clojure/src/main/java/example/Transactions.java
@@ -0,0 +1,180 @@
+package example;
+
+/*******************************************************************************
+ * Copyright (c) 1198, 2013 Oracle. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * dclarke - Dynamic Persistence INCUBATION - Enhancement 200045
+ * http://wiki.eclipse.org/EclipseLink/Development/JPA/Dynamic
+ *
+ * This code is being developed under INCUBATION and is not currently included
+ * in the automated EclipseLink build. The API in this code may change, or
+ * may never be included in the product. Please provide feedback through mailing
+ * lists or the bug database.
+ ******************************************************************************/
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.FlushModeType;
+
+import org.eclipse.persistence.config.PessimisticLock;
+import org.eclipse.persistence.config.QueryHints;
+import org.eclipse.persistence.dynamic.DynamicEntity;
+import org.eclipse.persistence.dynamic.DynamicHelper;
+import org.eclipse.persistence.dynamic.DynamicType;
+import org.eclipse.persistence.jpa.dynamic.JPADynamicHelper;
+
+/**
+ *
+ * @author dclarke
+ * @since EclipseLink - Dynamic Incubator (1.1.0-branch)
+ */
+public class Transactions {
+
+ /**
+ * New entities with new related related entities can be persisted using
+ * <code>EntityManager.persist(newEntity)</code>. The cascade setting on the
+ * mappings determine how the related entities are handled. In this case
+ * Employee has its relationship to Address and PhoneNumber configured with
+ * cascade-all so the associated new entities will also be persisted.
+ */
+ public DynamicEntity createUsingPersist(EntityManager em) {
+ DynamicHelper helper = new JPADynamicHelper(em);
+
+ DynamicType empType = helper.getType("Employee");
+ DynamicType addrType = helper.getType("Address");
+ DynamicType phoneType = helper.getType("PhoneNumber");
+
+ DynamicEntity emp = (DynamicEntity) empType.newDynamicEntity();
+ emp.set("firstName", "Sample");
+ emp.set("lastName", "Employee");
+ emp.set("gender", "Male");
+ emp.set("salary", 123456);
+
+ DynamicEntity address = (DynamicEntity) addrType.newDynamicEntity();
+ emp.set("address", address);
+
+ DynamicEntity phone = (DynamicEntity) phoneType.newDynamicEntity();
+ phone.set("type", "Mobile");
+ phone.set("areaCode", "613");
+ phone.set("number", "555-1212");
+ phone.set("owner", emp);
+ emp.<Collection<DynamicEntity>> get("phoneNumbers").add(phone);
+
+ em.getTransaction().begin();
+ em.persist(emp);
+ em.getTransaction().commit();
+
+ return emp;
+ }
+
+ /**
+ *
+ */
+ public DynamicEntity createUsingMerge(EntityManager em) {
+ JPADynamicHelper helper = new JPADynamicHelper(em);
+
+ DynamicEntity emp = helper.getType("Employee").newDynamicEntity();
+ emp.set("firstName", "Sample");
+ emp.set("lastName", "Employee");
+ emp.set("gender", "Male");
+ emp.set("salary", 123456);
+
+ DynamicEntity address = helper.getType("Address").newDynamicEntity();
+ emp.set("address", address);
+
+ DynamicEntity phone = helper.getType("PhoneNumber").newDynamicEntity();
+ phone.set("type", "Mobile");
+ phone.set("areaCode", "613");
+ phone.set("number", "555-1212");
+ phone.set("owner", emp);
+ emp.<Collection<DynamicEntity>> get("phoneNumbers").add(phone);
+
+ em.getTransaction().begin();
+ // When merging the managed instance is returned from the call.
+ // Further usage within the transaction must be done with this managed
+ // entity.
+ emp = (DynamicEntity) em.merge(emp);
+ em.getTransaction().commit();
+
+ return emp;
+ }
+
+ /**
+ *
+ * @param em
+ * @return
+ */
+ public DynamicEntity createWithRelationshipsToExistingEntities(EntityManager em) {
+ return null;
+ }
+
+ /**
+ *
+ * @param em
+ */
+ public DynamicEntity deleteEntity(EntityManager em) {
+ return null;
+ }
+
+ /**
+ * Example of in-memory query against the transactional state without
+ * flushing it to the database.
+ *
+ * @param em
+ */
+ public void queriesOnTransactionalState(EntityManager em) {
+ em.setFlushMode(FlushModeType.COMMIT);
+
+ }
+
+ /**
+ *
+ * @param em
+ * @throws Exception
+ */
+ public void pessimisticLocking(EntityManager em) throws Exception {
+
+ // Find the Employee with the minimum ID
+ int minId = new Queries().minimumEmployeeId(em);
+
+ em.getTransaction().begin();
+
+ // Lock Employee using query with hint
+ DynamicEntity emp = (DynamicEntity) em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID").setParameter("ID", minId).setHint(QueryHints.PESSIMISTIC_LOCK, PessimisticLock.Lock).getSingleResult();
+
+ emp.set("salary", emp.<Integer> get("salary") - 1);
+
+ em.flush();
+ }
+
+ /**
+ * This example illustrates the use of a query returning an entity and data
+ * from a related entity within a transaction. The returned entities are
+ * managed and thus any changes are reflected in the database upon flush.
+ *
+ * @param em
+ * @throws Exception
+ */
+ @SuppressWarnings("unchecked")
+ public void updateEmployeeWithCity(EntityManager em) throws Exception {
+ em.getTransaction().begin();
+
+ List<Object[]> emps = em.createQuery("SELECT e, e.address.city FROM Employee e").getResultList();
+ DynamicEntity emp = (DynamicEntity) emps.get(0)[0];
+ emp.set("salary", emp.<Integer> get("salary") + 1);
+
+ em.flush();
+
+ em.getTransaction().rollback();
+ }
+
+}
diff --git a/jpars.script.clojure/src/main/java/org/eclipse/persistence/dynamic/ReflectiveDynamicClassLoader.java b/jpars.script.clojure/src/main/java/org/eclipse/persistence/dynamic/ReflectiveDynamicClassLoader.java
new file mode 100644
index 0000000..db02059
--- /dev/null
+++ b/jpars.script.clojure/src/main/java/org/eclipse/persistence/dynamic/ReflectiveDynamicClassLoader.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
+ * which accompanies this distribution.
+ * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * dclarke - initial
+ ******************************************************************************/
+package org.eclipse.persistence.dynamic;
+
+import java.lang.reflect.Method;
+
+/**
+ * Extended {@link DynamicClassLoader} used to create classes using reflective
+ * access to defineClass. This causes the class to be created on the provided
+ * delegate/parent loader instead of just within this custom loader. Required
+ * for frameworks that don't take and use a loader.
+ *
+ * @author dclarke
+ * @since EclipseLink 2.4.2
+ */
+public class ReflectiveDynamicClassLoader extends DynamicClassLoader {
+
+ private Method defineClassMethod;
+
+ public ReflectiveDynamicClassLoader(ClassLoader delegate) {
+ super(delegate);
+ }
+
+ protected Method getDefineClassMethod() {
+ if (this.defineClassMethod == null) {
+ try {
+ this.defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass", new Class<?>[] { String.class, byte[].class, int.class, int.class });
+ this.defineClassMethod.setAccessible(true);
+ } catch (Exception e) {
+ throw new RuntimeException("ReflectiveDynamicClassLoader could not access defineClass method", e);
+ }
+ }
+ return this.defineClassMethod;
+ }
+
+ @Override
+ protected Class<?> defineDynamicClass(String name, byte[] b) {
+ try {
+ return (Class<?>) getDefineClassMethod().invoke(getParent(), new Object[] { name, b, 0, b.length });
+ } catch (Exception e) {
+ throw new RuntimeException("ReflectiveDynamicClassLoader falied to create class: " + name, e);
+ }
+ }
+
+}
diff --git a/jpars.script.clojure/src/main/webapp/WEB-INF/lib/clojure-1.5.1.jar b/jpars.script.clojure/src/main/webapp/WEB-INF/lib/clojure-1.5.1.jar
new file mode 100644
index 0000000..68e6713
--- /dev/null
+++ b/jpars.script.clojure/src/main/webapp/WEB-INF/lib/clojure-1.5.1.jar
Binary files differ
diff --git a/jpars.script.clojure/src/main/webapp/WEB-INF/web.xml b/jpars.script.clojure/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..838c2b1
--- /dev/null
+++ b/jpars.script.clojure/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,13 @@
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ version="3.0">
+
+ <data-source>
+ <name>java:app/env/TLDS</name>
+ <class-name>com.mysql.jdbc.Driver</class-name>
+ <server-name>localhost</server-name>
+ <url>jdbc:mysql://localhost:3306/employee</url>
+ <user>root</user>
+ <password>password</password>
+ </data-source>
+</web-app>
\ No newline at end of file
diff --git a/jpars.script.clojure/src/main/webapp/index.jsp b/jpars.script.clojure/src/main/webapp/index.jsp
new file mode 100644
index 0000000..9ad4c73
--- /dev/null
+++ b/jpars.script.clojure/src/main/webapp/index.jsp
@@ -0,0 +1,6 @@
+<html>
+<body>
+<h2>EclipseLink JPA-RS: Clojure Scripting</h2>
+<% %>
+</body>
+</html>