You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2010/12/02 12:24:54 UTC
svn commit: r1041330 [1/2] - in /openjpa/sandboxes/jest:
openjpa-examples/jest/src/main/java/demo/
openjpa-examples/jest/src/main/resources/WEB-INF/
openjpa-examples/jest/src/main/resources/demo/
openjpa-persistence/src/main/java/org/apache/openjpa/per...
Author: ppoddar
Date: Thu Dec 2 11:24:53 2010
New Revision: 1041330
URL: http://svn.apache.org/viewvc?rev=1041330&view=rev
Log:
OPENJPA-1851: Add a client to JEST
Added:
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/IOR.java (with props)
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java (with props)
openjpa/sandboxes/jest/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/jest/jest.js (with props)
Removed:
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/DojoFormatter.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/HTMLDocument.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/HTMLElement.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/HTMLTableFormatter.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/jest/showhide.js
Modified:
openjpa/sandboxes/jest/openjpa-examples/jest/src/main/java/demo/SimpleApp.java
openjpa/sandboxes/jest/openjpa-examples/jest/src/main/resources/WEB-INF/web.xml
openjpa/sandboxes/jest/openjpa-examples/jest/src/main/resources/demo/index.html
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractCommand.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Constants.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/DomainCommand.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ExceptionFormatter.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/FindCommand.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTCommand.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTContext.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTServlet.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JPAServletContext.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONObjectFormatter.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ObjectFormatter.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ProcessingException.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PropertiesCommand.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PropertiesFormatter.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PrototypeFactory.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/QueryCommand.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/XMLFormatter.java
openjpa/sandboxes/jest/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/jest/index.html
openjpa/sandboxes/jest/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/jest/jest-instance.xsd
openjpa/sandboxes/jest/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/jest/jest.css
openjpa/sandboxes/jest/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/jest/localizer.properties
Modified: openjpa/sandboxes/jest/openjpa-examples/jest/src/main/java/demo/SimpleApp.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-examples/jest/src/main/java/demo/SimpleApp.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-examples/jest/src/main/java/demo/SimpleApp.java (original)
+++ openjpa/sandboxes/jest/openjpa-examples/jest/src/main/java/demo/SimpleApp.java Thu Dec 2 11:24:53 2010
@@ -48,7 +48,7 @@ import javax.servlet.http.HttpServletRes
*/
@SuppressWarnings("serial")
public class SimpleApp extends HttpServlet {
-
+ EntityManagerFactory _emf;
private static String UNIT_NAME = "jestdemo";
@Override
@@ -58,14 +58,17 @@ public class SimpleApp extends HttpServl
try {
Map<String,Object> props = new HashMap<String, Object>();
props.put("openjpa.EntityManagerFactoryPool", "true");
- EntityManagerFactory emf = Persistence.createEntityManagerFactory(UNIT_NAME, props);
- new DataLoader().populate(emf.createEntityManager());
+ _emf = Persistence.createEntityManagerFactory(UNIT_NAME, props);
+ new DataLoader().populate(_emf.createEntityManager());
} catch (Exception e) {
throw new ServletException(e);
}
config.getServletContext().log("Initialized with persistence unit [" + UNIT_NAME + "]");
}
+ /**
+ * The only response by this application is an <code>index.html</code> file.
+ */
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
@@ -75,4 +78,11 @@ public class SimpleApp extends HttpServl
out.write((char)c);
}
}
+
+ @Override
+ public void destroy() {
+ if (_emf != null) {
+ _emf.close();
+ }
+ }
}
Modified: openjpa/sandboxes/jest/openjpa-examples/jest/src/main/resources/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-examples/jest/src/main/resources/WEB-INF/web.xml?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-examples/jest/src/main/resources/WEB-INF/web.xml (original)
+++ openjpa/sandboxes/jest/openjpa-examples/jest/src/main/resources/WEB-INF/web.xml Thu Dec 2 11:24:53 2010
@@ -23,6 +23,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Demo Application with JEST Servlet</display-name>
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ </welcome-file-list>
<description>
An example of deploying a simple web application with JEST servlet.
This descriptor specifies the Demo Application servlet as well as JEST servlet.
@@ -45,7 +48,7 @@
</servlet>
<servlet-mapping>
<servlet-name>demo</servlet-name>
- <url-pattern>/app/*</url-pattern>
+ <url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Deployment descriptor for JESTServlet. -->
@@ -66,6 +69,10 @@
<param-name>persistence.unit</param-name>
<param-value>jestdemo</param-value>
</init-param>
+ <init-param>
+ <param-name>debug</param-name>
+ <param-value>true</param-value>
+ </init-param>
</servlet>
<servlet-mapping>
<servlet-name>jest</servlet-name>
Modified: openjpa/sandboxes/jest/openjpa-examples/jest/src/main/resources/demo/index.html
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-examples/jest/src/main/resources/demo/index.html?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-examples/jest/src/main/resources/demo/index.html (original)
+++ openjpa/sandboxes/jest/openjpa-examples/jest/src/main/resources/demo/index.html Thu Dec 2 11:24:53 2010
@@ -19,7 +19,6 @@ under the License.
<html>
<head>
<style type="text/css">
-hr {color:sienna;}
p {margin-left:20px;}
body {background-image:url("images/back40.gif");
.tag {
@@ -31,7 +30,10 @@ body {background-image:url("images/back4
<body>
<h1>DNA: Do-Nothing Application</h1>
<hr>
- This DNA application is deployed as a HTTP Servlet.<br>
+ <span style="font-size:1.2em;color:green;font-weight:bold">DNA application is used to demonstrate </span>
+ <A HREF="./jest/">JEST</A>.
+ <br>
+ DNA application is deployed as a HTTP Servlet.<br>
The servlet creates an OpenJPA persistence unit at initialization.<br>
@@ -39,13 +41,10 @@ body {background-image:url("images/back4
The fact that you are reading this page means the persistence unit has been initialized.
<p>
- <span style="font-size:1.2em;color:green;font-weight:bold">DNA application is used to demonstrate </span>
- <A HREF="./jest/">JEST</A>.
- <br>
- <h2>Requirement for JEST</h2>
+ <h2>Requirement for enabling JEST</h2>
- The only requirements for an application to enable JEST are
+ The requirements for an application to enable JEST are
<p>
► JEST Servlet must be <A href="#web.xml">deployed</A> within the same module scope of the application. <br>
@@ -72,7 +71,7 @@ body {background-image:url("images/back4
</servlet>
<servlet-mapping>
<servlet-name></span><span style="color:blue;">demo</span><span style="color:gray;font-weight:bold;"></servlet-name>
- <url-pattern></span><span style="color:blue;">/app/*</span><span style="color:gray;font-weight:bold;"></url-pattern>
+ <url-pattern></span><span style="color:blue;">/*</span><span style="color:gray;font-weight:bold;"></url-pattern>
</servlet-mapping>
<span style="color:green;font-weight:bold;"><!-- Deployment descriptor for JESTServlet. --></span>
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractCommand.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractCommand.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractCommand.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractCommand.java Thu Dec 2 11:24:53 2010
@@ -20,10 +20,8 @@
package org.apache.openjpa.persistence.jest;
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
-import static org.apache.openjpa.persistence.jest.Constants.*;
-import static org.apache.openjpa.persistence.jest.Constants.EQUAL;
-import static org.apache.openjpa.persistence.jest.Constants.FORMAT_DEFAULT;
-import static org.apache.openjpa.persistence.jest.Constants.PATH_SEPARATOR;
+import static org.apache.openjpa.persistence.jest.Constants.QUALIFIER_FORMAT;
+import static org.apache.openjpa.persistence.jest.Constants._loc;
import java.io.IOException;
import java.io.PrintWriter;
@@ -49,20 +47,26 @@ import org.apache.openjpa.kernel.OpenJPA
*
*/
abstract class AbstractCommand implements JESTCommand {
- protected ObjectFormatter _formatter;
- protected static PrototypeFactory<ObjectFormatter> _ff = new PrototypeFactory<ObjectFormatter>();
+ public static final char EQUAL = '=';
+ public static final String PATH_SEPARATOR = "/";
+ public static final Collection<String> EMPTY_LIST = Collections.emptySet();
+ protected ObjectFormatter<?> _formatter;
+ protected static PrototypeFactory<Format,ObjectFormatter<?>> _ff =
+ new PrototypeFactory<Format,ObjectFormatter<?>>();
private Map<String, String> _qualifiers = new HashMap<String, String>();
private Map<String, String> _args = new HashMap<String, String>();
private Map<String, String> _margs = new HashMap<String, String>();
+ protected final JPAServletContext ctx;
static {
- _ff.register(FORMAT_XML, XMLFormatter.class);
- _ff.register(FORMAT_JSON, JSONObjectFormatter.class);
- _ff.register(FORMAT_DOJO, DojoFormatter.class);
- _ff.register(FORMAT_HTML, HTMLTableFormatter.class);
-
+ _ff.register(Format.xml, XMLFormatter.class);
+ _ff.register(Format.json, JSONObjectFormatter.class);
+ }
+ protected AbstractCommand(JPAServletContext ctx) {
+ this.ctx = ctx;
}
+
public String getMandatoryArgument(String key) {
return get(key, _margs);
}
@@ -108,7 +112,8 @@ abstract class AbstractCommand implement
* <br>
* The qualifiers and arguments are immutable after parse.
*/
- public void parse(HttpServletRequest request) throws ProcessingException {
+ public void parse() throws ProcessingException {
+ HttpServletRequest request = ctx.getRequest();
String path = request.getPathInfo();
if (path != null) {
path = path.substring(1);
@@ -130,12 +135,13 @@ abstract class AbstractCommand implement
while (names.hasMoreElements()) {
String key = names.nextElement().toString();
+ if (key.startsWith("dojo.")) continue;
put(key, request.getParameter(key), mandatoryArgs.contains(key) ? _margs : _args);
}
_args = Collections.unmodifiableMap(_args);
_margs = Collections.unmodifiableMap(_margs);
- validate(request);
+ validate();
}
/**
@@ -157,6 +163,19 @@ abstract class AbstractCommand implement
}
/**
+ * Gets the maximum number of arguments excluding the mandatory arguments.
+ *
+ * @return Integer.MAX_VALUE by default.
+ */
+ protected int getMaximumArguments() {
+ return Integer.MAX_VALUE;
+ }
+
+ protected Format getDefaultFormat() {
+ return Format.xml;
+ }
+
+ /**
* Gets the valid qualifiers.
*
* @return empty list by default.
@@ -168,23 +187,28 @@ abstract class AbstractCommand implement
/**
* Called post-parse to validate this command has requisite qualifiers and arguments.
*/
- protected void validate(HttpServletRequest request) {
+ protected void validate() {
+ HttpServletRequest request = ctx.getRequest();
Collection<String> validQualifiers = getValidQualifiers();
for (String key : _qualifiers.keySet()) {
if (!validQualifiers.contains(key)) {
- throw new ProcessingException(_loc.get("parse-invalid-qualifier", this, key, validQualifiers),
+ throw new ProcessingException(ctx,_loc.get("parse-invalid-qualifier", this, key, validQualifiers),
HTTP_BAD_REQUEST);
}
}
Collection<String> mandatoryArgs = getMandatoryArguments();
for (String key : mandatoryArgs) {
if (request.getParameter(key) == null) {
- throw new ProcessingException(_loc.get("parse-missing-mandatory-argument", this, key,
+ throw new ProcessingException(ctx, _loc.get("parse-missing-mandatory-argument", this, key,
request.getParameterMap().keySet()), HTTP_BAD_REQUEST);
}
}
if (_args.size() < getMinimumArguments()) {
- throw new ProcessingException(_loc.get("parse-less-argument", this, _args.keySet(),
+ throw new ProcessingException(ctx, _loc.get("parse-less-argument", this, _args.keySet(),
+ getMinimumArguments()), HTTP_BAD_REQUEST);
+ }
+ if (_args.size() > getMaximumArguments()) {
+ throw new ProcessingException(ctx, _loc.get("parse-less-argument", this, _args.keySet(),
getMinimumArguments()), HTTP_BAD_REQUEST);
}
}
@@ -201,17 +225,23 @@ abstract class AbstractCommand implement
return map.containsKey(key);
}
- public ObjectFormatter<?> getObjectFormatter(JPAServletContext ctx) {
+ public ObjectFormatter<?> getObjectFormatter() {
if (_formatter == null) {
- String format = getQualifier(QUALIFIER_FORMAT);
- if (format == null) {
- format = ctx.getRequest().getSession().getServletContext().getInitParameter(INIT_PARA_FORMAT);
- if (format == null)
- format = FORMAT_DEFAULT;
+ String rformat = getQualifier(QUALIFIER_FORMAT);
+ Format format = null;
+ if (rformat == null) {
+ format = getDefaultFormat();
+ } else {
+ try {
+ format = Format.valueOf(rformat);
+ } catch (Exception e) {
+ throw new ProcessingException(ctx, _loc.get("format-not-supported", new Object[]{format,
+ ctx.getRequest().getPathInfo(), _ff.getRegisteredKeys()}), HTTP_BAD_REQUEST);
+ }
}
_formatter = _ff.newInstance(format);
if (_formatter == null) {
- throw new ProcessingException(_loc.get("format-not-supported", new Object[]{format,
+ throw new ProcessingException(ctx, _loc.get("format-not-supported", new Object[]{format,
ctx.getRequest().getPathInfo(), _ff.getRegisteredKeys()}), HTTP_BAD_REQUEST);
}
}
@@ -240,7 +270,7 @@ abstract class AbstractCommand implement
protected void debug(HttpServletRequest request, HttpServletResponse response, JPAServletContext ctx)
throws IOException {
- response.setContentType(MIME_TYPE_PLAIN);
+ response.setContentType(Constants.MIME_TYPE_PLAIN);
PrintWriter writer = response.getWriter();
writer.println("URI = [" + request.getRequestURI() + "]");
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Constants.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Constants.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Constants.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Constants.java Thu Dec 2 11:24:53 2010
@@ -19,12 +19,7 @@
package org.apache.openjpa.persistence.jest;
-import java.text.SimpleDateFormat;
-import java.util.Collection;
-import java.util.Collections;
-
import org.apache.openjpa.lib.util.Localizer;
-import org.apache.openjpa.persistence.jest.HTMLElement.Tag;
/**
* Static String constants
@@ -34,24 +29,6 @@ import org.apache.openjpa.persistence.je
*/
public interface Constants {
/**
- * Character constants
- */
- public static final char EQUAL = '=';
- public static final char START = '<';
- public static final char END = '>';
- public static final char SLASH = '/';
- public static final char QUOTE = '"';
- public static final char DOT = '.';
- public static final char UNDERSCORE = '_';
- public static final char DASH = '-';
- public static final char HASH = '#';
- public static final String EMPTY = "";
- public static final String SPACE = " ";
- public static final String NEWLINE = "\r\n";
- public static final String PATH_SEPARATOR = "/";
- public static final String KEY_VALUE_SEPARATOR = " : ";
-
- /**
* Command Qualifiers
*/
public static final String QUALIFIER_FORMAT = "format";
@@ -67,14 +44,6 @@ public interface Constants {
public static final String ARG_QUERY = "q";
public static final String ARG_TYPE = "type";
- /**
- * Supported format monikers.
- */
- public static final String FORMAT_XML = "xml";
- public static final String FORMAT_JSON = "json";
- public static final String FORMAT_DOJO = "dojo";
- public static final String FORMAT_HTML = "html";
- public static final String FORMAT_DEFAULT = "html";
/**
* Mime Types
@@ -82,58 +51,66 @@ public interface Constants {
public static final String MIME_TYPE_PLAIN = "text/plain";
public static final String MIME_TYPE_JS = "text/javascript";
public static final String MIME_TYPE_CSS = "text/css";
- public static final String MIME_TYPE_HTML = "text/html";
public static final String MIME_TYPE_XML = "text/xml";
public static final String MIME_TYPE_JSON = "application/json";
public static final String CONTEXT_ROOT = "/";
+ public static final String JEST_TEMPLATE = "jest.html";
/**
* Servlet initialization parameters
*/
- public static final String INIT_PARA_FORMAT = "response.format";
- public static final String INIT_PARA_UNIT = "persistence.unit";
+ public static final String INIT_PARA_UNIT = "persistence.unit";
+ public static final String INIT_PARA_STANDALONE = "standalone";
/**
* Dojo Toolkit URL and Themes
*/
- public static final String DOJO_URL = "http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js";
- public static final String DOJO_CSS_URL = "http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/";
- public static final String DOJO_THEME = "claro";
+ public static final String DOJO_BASE_URL = "http://ajax.googleapis.com/ajax/libs/dojo/1.5";
+ public static final String DOJO_THEME = "claro";
- /**
- * HTML divisions used by Dojo JavaScript
- */
- public static final String HTML_DIV_CANVAS = "canvas";
- public static final String HTML_DIV_DATA = "data";
+
/**
- * CSS styles
+ * Root element of XML instances. Must match the name defined in <A href="jest-instance.xsd>jest-instance.xsd</A>.
*/
- public static final String CSS_INVISIBLE = "display:none;";
- public static final String CSS_ERROR_MESSSAGE = "error-message";
- public static final String CSS_ERROR_HEADER = "error-header";
- public static final String CSS_EVEN_ROW = "even";
- public static final String CSS_ODD_ROW = "odd";
- public static final String CSS_DATA_TABLE = "data";
-
+ public static final String ROOT_ELEMENT_INSTANCE = "instances";
+ public static final String ATTR_ID = "id";
public static final String ATTR_REL = "rel";
public static final String ATTR_SRC = "src";
public static final String ATTR_TYPE = "type";
public static final String ATTR_NAME = "name";
public static final String ATTR_VERSION = "version";
public static final String ATTR_CLASS = "class";
- public static final String HREF = "href";
- public static final String STYLESHEET = "stylesheet";
- public static final String STYLE = "style";
- public static final String REL = "rel";
- public static final String ATTR_ID = "id";
+ public static final String ATTR_HREF = "href";
+ public static final String ATTR_STYLE = "style";
+ public static final String ATTR_NULL = "null";
+ public static final String ATTR_MEMBER_TYPE = "member-type";
+ public static final String ATTR_KEY_TYPE = "key-type";
+ public static final String ATTR_VALUE_TYPE = "value-type";
/**
- * Root element of XML instances. Must match the name defined in <A href="jest-instance.xsd>jest-instance.xsd</A>.
+ * Elements and attributes in properties XML.
*/
- public static final String ELEMENT_ROOT_INSTANCE = "instances";
+ public static final String ROOT_ELEMENT_PROPERTIES = "properties";
+ public static final String ELEMENT_PROPERTY = "property";
+ public static final String ATTR_PROPERTY_KEY = "name";
+ public static final String ATTR_PROPERTY_VALUE = "value";
+
+
+ public static final String ROOT_ELEMENT_ERROR = "error";
+ public static final String ELEMENT_ERROR_HEADER = "error-code";
+ public static final String ELEMENT_ERROR_MESSAGE = "error-message";
+ public static final String ELEMENT_ERROR_TRACE = "stacktrace";
+
+ /**
+ * Root element of XML meta-model. Must match the name defined in <A href="jest-model.xsd>jest-model.xsd</A>.
+ */
+ public static final String ROOT_ELEMENT_MODEL = "metamodel";
+
public static final String ELEMENT_INSTANCE = "instance";
+ public static final String ELEMENT_URI = "uri";
+ public static final String ELEMENT_DESCRIPTION = "description";
public static final String ELEMENT_REF = "ref";
public static final String ELEMENT_NULL_REF = "null";
public static final String ELEMENT_MEMBER = "member";
@@ -141,64 +118,24 @@ public interface Constants {
public static final String ELEMENT_ENTRY_KEY = "key";
public static final String ELEMENT_ENTRY_VALUE = "value";
- /**
- * Root element of XML meta-model. Must match the name defined in <A href="jest-instance.xsd>jest-model.xsd</A>.
- */
- public static final String ELEMENT_DOMAIN = "metamodel";
- public static final String NULL_VALUE = EMPTY;
- public static final String ATTR_NULL = "null";
- public static final String ATTR_MEMBER_TYPE = "member-type";
- public static final String ATTR_KEY_TYPE = "key-type";
- public static final String ATTR_VALUE_TYPE = "value-type";
/**
* JEST resources
*/
- public static final String JEST_ROOT_RESOURCE = "index.html";
- public static final String JEST_STYLESHEET = "jest.css";
- public static final String JEST_SCRIPT_INSTANCES = "instances.js";
- public static final String JEST_SCRIPT_DOMAIN = "domain.js";
+// public static final String JEST_STYLESHEET = "jest.css";
+// public static final String JEST_SCRIPT_INSTANCES = "instances.js";
+// public static final String JEST_SCRIPT_DOMAIN = "model.js";
public static final String JEST_INSTANCE_XSD = "jest-instance.xsd";
- /**
- * JEST Cascaded StyleSheet.
- */
- public static final HTMLElement CSS_JEST = new HTMLElement(Tag.link).set(
- ATTR_REL, STYLESHEET,
- ATTR_TYPE, MIME_TYPE_CSS,
- HREF, JEST_STYLESHEET).createTemplate();
-
- /**
- * JavaScript to render object graph using dojo widgets.
- */
- static HTMLElement JEST_INSTANCE_SCRIPT = new HTMLElement(Tag.script).set(
- ATTR_SRC, JEST_SCRIPT_INSTANCES,
- ATTR_TYPE, MIME_TYPE_JS).createTemplate();
-
- /**
- * JavaScript to render domain model using dojo widgets.
- */
- static HTMLElement JEST_DOMAIN_SCRIPT = new HTMLElement(Tag.script).set(
- ATTR_SRC, JEST_SCRIPT_DOMAIN,
- ATTR_TYPE, MIME_TYPE_JS).createTemplate();
-
-
-
- /**
- * XML constants
- */
- public static final String DOCTYPE_STRICT = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\""
- + " \"http://www.w3.org/TR/html4/strict.dtd\">";
static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
/**
* Common instances
*/
- public static final Collection<String> EMPTY_LIST = Collections.emptySet();
- public static final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy");
public static final Localizer _loc = Localizer.forPackage(JESTContext.class);
+ public static final String NULL_VALUE = "null";
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/DomainCommand.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/DomainCommand.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/DomainCommand.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/DomainCommand.java Thu Dec 2 11:24:53 2010
@@ -20,7 +20,12 @@
package org.apache.openjpa.persistence.jest;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import static org.apache.openjpa.persistence.jest.Constants.ARG_TYPE;
+import static org.apache.openjpa.persistence.jest.Constants._loc;
/**
* Marshals a JPA meta-model in the configured format to the response output stream.
@@ -29,12 +34,27 @@ import java.io.IOException;
*
*/
class DomainCommand extends AbstractCommand {
+ private static final List<String> _validQualifiers = Arrays.asList("format");
+
+ public DomainCommand(JPAServletContext ctx) {
+ super(ctx);
+ }
+
+ protected Collection<String> getValidQualifiers() {
+ return _validQualifiers;
+ }
+
+ protected int getMaximumArguments() {
+ return 0;
+ }
public String getAction() {
return "domain";
}
- public void process(JPAServletContext ctx) throws ProcessingException, IOException {
- getObjectFormatter(ctx).writeOut(ctx.getPersistenceContext().getMetamodel(), ctx.getResponse().getWriter());
+ public void process() throws ProcessingException, IOException {
+ getObjectFormatter().writeOut(ctx.getPersistenceContext().getMetamodel(),
+ _loc.get("domain-title").toString(), _loc.get("domain-desc").toString(), ctx.getRequestURI(),
+ ctx.getResponse().getOutputStream());
}
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ExceptionFormatter.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ExceptionFormatter.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ExceptionFormatter.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ExceptionFormatter.java Thu Dec 2 11:24:53 2010
@@ -19,15 +19,12 @@
package org.apache.openjpa.persistence.jest;
-import static org.apache.openjpa.persistence.jest.Constants.CSS_JEST;
-import static org.apache.openjpa.persistence.jest.Constants.ATTR_CLASS;
-import static org.apache.openjpa.persistence.jest.Constants.CSS_ERROR_HEADER;
-import static org.apache.openjpa.persistence.jest.Constants.CSS_ERROR_MESSSAGE;
-
import java.io.PrintWriter;
import java.io.StringWriter;
-import org.apache.openjpa.persistence.jest.HTMLElement.Tag;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
/**
* Formats error stack trace.
@@ -35,24 +32,31 @@ import org.apache.openjpa.persistence.je
* @author Pinaki Poddar
*
*/
-class ExceptionFormatter {
+class ExceptionFormatter extends XMLFormatter {
/**
- * Creates a HTML Document with given header and stack trace of the given error.
+ * Creates a XML Document with given header and stack trace of the given error.
* @param header
* @param e
*/
- public HTMLDocument createHTML(String header, Throwable e) {
- HTMLDocument html = new HTMLDocument();
- html.getHead().add(CSS_JEST);
+ public Document createXML(String code, String message, Throwable e) {
+ Element root = newDocument(Constants.ROOT_ELEMENT_ERROR);
+ Document doc = root.getOwnerDocument();
+ Element errorCode = doc.createElement(Constants.ELEMENT_ERROR_HEADER);
+ Element errorMessage = doc.createElement(Constants.ELEMENT_ERROR_MESSAGE);
+ Element stackTrace = doc.createElement(Constants.ELEMENT_ERROR_TRACE);
+
+ errorCode.setTextContent(code);
+ errorMessage.appendChild(doc.createCDATASection(e.getMessage()));
StringWriter buf = new StringWriter();
e.printStackTrace(new PrintWriter(buf, true));
- html.getBody()
- .add(new HTMLElement(Tag.p).set(ATTR_CLASS, CSS_ERROR_HEADER).setBody(header),
- new HTMLElement(Tag.p).set(ATTR_CLASS, CSS_ERROR_MESSSAGE).setBody(e.getLocalizedMessage()),
- new HTMLElement(Tag.p).setBody("Error Stack Trace:"),
- new HTMLElement(Tag.pre).setBody(buf.toString()));
- return html;
+ stackTrace.appendChild(doc.createCDATASection(buf.toString()));
+
+ root.appendChild(errorCode);
+ root.appendChild(errorMessage);
+ root.appendChild(stackTrace);
+
+ return doc;
}
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/FindCommand.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/FindCommand.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/FindCommand.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/FindCommand.java Thu Dec 2 11:24:53 2010
@@ -44,6 +44,10 @@ class FindCommand extends AbstractComman
private static final List<String> _mandatoryArgs = Arrays.asList(ARG_TYPE);
private static final List<String> _validQualifiers = Arrays.asList("format", "plan");
+ public FindCommand(JPAServletContext ctx) {
+ super(ctx);
+ }
+
@Override
protected Collection<String> getMandatoryArguments() {
return _mandatoryArgs;
@@ -59,7 +63,7 @@ class FindCommand extends AbstractComman
}
@Override
- public void process(JPAServletContext ctx) throws ProcessingException {
+ public void process() throws ProcessingException {
EntityManager em = ctx.getPersistenceContext();
String type = getMandatoryArgument(ARG_TYPE);
ClassMetaData meta = ctx.resolve(type);
@@ -73,15 +77,17 @@ class FindCommand extends AbstractComman
Object pc = em.find(meta.getDescribedType(), oid);
if (pc != null) {
OpenJPAStateManager sm = toStateManager(pc);
- ObjectFormatter<?> formatter = getObjectFormatter(ctx);
+ ObjectFormatter<?> formatter = getObjectFormatter();
ctx.getResponse().setContentType(formatter.getMimeType());
try {
- formatter.writeOut(Collections.singleton(sm), em.getMetamodel(), ctx.getResponse().getWriter());
+ formatter.writeOut(Collections.singleton(sm), em.getMetamodel(),
+ _loc.get("find-title").toString(), _loc.get("find-desc").toString(), ctx.getRequestURI(),
+ ctx.getResponse().getOutputStream());
} catch (IOException e) {
- throw new ProcessingException(e);
+ throw new ProcessingException(ctx, e);
}
} else {
- throw new ProcessingException(_loc.get("entity-not-found", type, Arrays.toString(pks)),
+ throw new ProcessingException(ctx, _loc.get("entity-not-found", type, Arrays.toString(pks)),
HttpURLConnection.HTTP_NOT_FOUND);
}
}
Added: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/IOR.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/IOR.java?rev=1041330&view=auto
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/IOR.java (added)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/IOR.java Thu Dec 2 11:24:53 2010
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.jest;
+
+import static org.apache.openjpa.persistence.jest.Constants.NULL_VALUE;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * String reference of a managed object.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class IOR {
+ public static final char DASH = '-';
+ /**
+ * Stringified representation of a managed instance identity.
+ * The simple Java type name and the persistent identity separated by a {@link Constants#DASH dash}.
+ *
+ * @param sm a managed instance.
+ * @return
+ */
+ public static String toString(OpenJPAStateManager sm) {
+ if (sm == null) return NULL_VALUE;
+ return sm.getMetaData().getDescribedType().getSimpleName() + DASH + sm.getObjectId();
+ }
+}
Propchange: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/IOR.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/IOR.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTCommand.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTCommand.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTCommand.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTCommand.java Thu Dec 2 11:24:53 2010
@@ -57,6 +57,10 @@ import javax.servlet.http.HttpServletReq
*
*/
public interface JESTCommand {
+ /**
+ * Supported format monikers.
+ */
+ public static enum Format {xml, json};
/**
* Parse the given request to populate qualifiers and parameters of this command.
@@ -64,10 +68,8 @@ public interface JESTCommand {
* original request. During {@link #process(ServletRequest, ServletResponse, JPAServletContext) processing}
* phase, the parameters and qualifiers are accessed from the parsed command itself rather than
* from the
- *
- * @param request a HTTP request
*/
- public void parse(HttpServletRequest request) throws ProcessingException;
+ public void parse() throws ProcessingException;
/**
* Accessors for this command's arguments and qualifiers.
@@ -83,9 +85,8 @@ public interface JESTCommand {
/**
* Process the given request and write the output on to the given response in the given context.
- * @param ctx the operational context.
* @throws ProcessingException
*
*/
- public void process(JPAServletContext ctx) throws ProcessingException, IOException;
+ public void process() throws ProcessingException, IOException;
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTContext.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTContext.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTContext.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTContext.java Thu Dec 2 11:24:53 2010
@@ -19,11 +19,18 @@
package org.apache.openjpa.persistence.jest;
+import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
+import static org.apache.openjpa.persistence.jest.Constants.CONTEXT_ROOT;
+import java.io.ByteArrayOutputStream;
+import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Calendar;
import java.util.Date;
@@ -37,7 +44,6 @@ import org.apache.openjpa.meta.ClassMeta
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import static org.apache.openjpa.persistence.jest.Constants.*;
/**
* An operational context combines a {@link OpenJPAEntityManager persistence context} and a HTTP execution
@@ -56,10 +62,12 @@ public class JESTContext implements JPAS
private final HttpServletRequest _request;
private final HttpServletResponse _response;
protected MetaDataRepository _repos;
+ private String _rootResource;
protected Log _log;
- protected static PrototypeFactory<JESTCommand> _cf = new PrototypeFactory<JESTCommand>();
+ protected static PrototypeFactory<String,JESTCommand> _cf = new PrototypeFactory<String,JESTCommand>();
public static final Localizer _loc = Localizer.forPackage(JESTContext.class);
private static final String ONE_YEAR_FROM_NOW;
+ public static final char QUERY_SEPARATOR = '?';
/**
* Registers known commands in a {@link PrototypeFactory registry}.
@@ -113,6 +121,23 @@ public class JESTContext implements JPAS
}
/**
+ *
+ */
+ public URI getRequestURI() {
+ StringBuffer buf = _request.getRequestURL();
+ String query = _request.getQueryString();
+ if (query != null) {
+ buf.append(QUERY_SEPARATOR).append(query);
+ }
+ try {
+ return new URI(buf.toString());
+ } catch (URISyntaxException e) {
+ throw new ProcessingException(this, _loc.get("bad-uri", _request.getRequestURL()), HTTP_INTERNAL_ERROR);
+ }
+
+ }
+
+ /**
* Gets the response.
*/
public HttpServletResponse getResponse() {
@@ -127,7 +152,7 @@ public class JESTContext implements JPAS
* if a action with the given key is registered then the control is delegated to the command.
* The command parses the entire {@link HttpServletRequest request} for requisite qualifiers and
* arguments and if the parse is successful then the command is
- * {@linkplain JESTCommand#process(JPAServletContext) executed} in this context.
+ * {@linkplain JESTCommand#process() executed} in this context.
* <br>
* If path is null, or no command is registered for the action or the command can not parse
* the request, then a last ditch attempt is made to {@linkplain #findResource(String) find} a resource.
@@ -148,26 +173,27 @@ public class JESTContext implements JPAS
* @throws Exception
*/
public void execute() throws Exception {
- debug(_request);
String path = _request.getPathInfo();
- if (path == null || CONTEXT_ROOT.equals(path)) {
- findResource(JEST_ROOT_RESOURCE);
+ if (isContextRoot(path)) {
+ getRootResource();
return;
}
String action = getAction(path);
- JESTCommand command = _cf.newInstance(action);
+ JESTCommand command = _cf.newInstance(action, this);
if (command == null) {
findResource(path.substring(1));
return;
}
try {
- command.parse(_request);
- command.process(this);
- } catch (Exception e) {
+ command.parse();
+ command.process();
+ } catch (ProcessingException e1) {
+ throw e1;
+ } catch (Exception e2) {
try {
findResource(path.substring(action.length()+1));
- } catch (ProcessingException e2) {
- throw e;
+ } catch (ProcessingException e3) {
+ throw e2;
}
}
}
@@ -204,14 +230,14 @@ public class JESTContext implements JPAS
* @throws ProcessingException
*/
void findResource(String rsrc) throws ProcessingException {
- _response.setHeader("Cache-Control", "public");
- _response.setHeader("Expires", ONE_YEAR_FROM_NOW);
+// _response.setHeader("Cache-Control", "public");
+// _response.setHeader("Expires", ONE_YEAR_FROM_NOW);
InputStream in = getClass().getResourceAsStream(rsrc);
if (in == null) { // try again as a relative path
if (rsrc.startsWith(CONTEXT_ROOT)) {
in = getClass().getResourceAsStream(rsrc.substring(1));
if (in == null) {
- throw new ProcessingException(_loc.get("resource-not-found", rsrc), HTTP_NOT_FOUND);
+ throw new ProcessingException(this, _loc.get("resource-not-found", rsrc), HTTP_NOT_FOUND);
}
}
}
@@ -233,9 +259,10 @@ public class JESTContext implements JPAS
}
}
} catch (IOException e) {
- throw new ProcessingException(e, _loc.get("resource-not-found", rsrc), HTTP_NOT_FOUND);
+ throw new ProcessingException(this, e, _loc.get("resource-not-found", rsrc), HTTP_NOT_FOUND);
}
}
+
private void log(String s) {
@@ -255,14 +282,49 @@ public class JESTContext implements JPAS
}
}
- private void debug(HttpServletRequest request) {
- log("-----------------------------------------------------------");
- log("Request URL = [" + request.getRequestURL() + "]");
- log("Request URI = [" + request.getRequestURI() + "]");
- log("Servlet Path = [" + request.getServletPath() + "]");
- log("Context Path = [" + request.getContextPath() + "]");
- log("Path Info = [" + request.getPathInfo() + "]");
- log("Path Translated = [" + request.getPathTranslated() + "]");
+ /**
+ * Is this path a context root?
+ * @param path
+ * @return
+ */
+ boolean isContextRoot(String path) {
+ return (path == null || CONTEXT_ROOT.equals(path));
}
+ /**
+ * Root resource is a HTML template with deployment specific tokens such as name of the persistence unit
+ * or base url. On first request for this resource, the tokens in the templated HTML file gets replaced
+ * by the actual deployment specific value into a string. This string (which is an entire HTML file)
+ * is then written to the response.
+ *
+ * @see TokenReplacedStream
+ * @throws IOException
+ */
+ private void getRootResource() throws IOException {
+ _response.setHeader("Cache-Control", "public");
+ _response.setHeader("Expires", ONE_YEAR_FROM_NOW);
+ if (_rootResource == null) {
+ String[] tokens = {
+ "${persistence.unit}", getPersistenceUnitName(),
+ "${jest.uri}", _request.getRequestURL().toString(),
+ "${webapp.name}", _request.getContextPath().startsWith(CONTEXT_ROOT)
+ ? _request.getContextPath().substring(1)
+ : _request.getContextPath(),
+ "${servlet.name}", _request.getServletPath().startsWith(CONTEXT_ROOT)
+ ? _request.getServletPath().substring(1)
+ : _request.getServletPath(),
+ "${server.name}", _request.getServerName(),
+ "${server.port}", ""+_request.getServerPort(),
+
+ "${dojo.base}", Constants.DOJO_BASE_URL,
+ "${dojo.theme}", Constants.DOJO_THEME,
+
+ };
+ InputStream in = getClass().getResourceAsStream(Constants.JEST_TEMPLATE);
+ CharArrayWriter out = new CharArrayWriter();
+ new TokenReplacedStream().replace(in, out, tokens);
+ _rootResource = out.toString();
+ }
+ _response.getOutputStream().write(_rootResource.getBytes());
+ }
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTServlet.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTServlet.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTServlet.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTServlet.java Thu Dec 2 11:24:53 2010
@@ -19,8 +19,15 @@
package org.apache.openjpa.persistence.jest;
+import static org.apache.openjpa.persistence.jest.Constants.INIT_PARA_UNIT;
+import static org.apache.openjpa.persistence.jest.Constants.INIT_PARA_STANDALONE;
+import static org.apache.openjpa.persistence.jest.Constants._loc;
+
import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import javax.persistence.Persistence;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -29,10 +36,9 @@ import javax.servlet.http.HttpServletRes
import org.apache.openjpa.kernel.AbstractBrokerFactory;
import org.apache.openjpa.kernel.BrokerFactory;
-import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.persistence.JPAFacadeHelper;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
-import static org.apache.openjpa.persistence.jest.Constants.*;
+import org.apache.openjpa.persistence.OpenJPAPersistence;
/**
* A specialized HTTP servlet to interpret HTTP requests as Java Persistent API commands
@@ -60,17 +66,24 @@ import static org.apache.openjpa.persist
*
*/
@SuppressWarnings("serial")
-public class JESTServlet extends HttpServlet {
+public class JESTServlet extends HttpServlet {
private String _unit;
+ private boolean _debug;
private OpenJPAEntityManagerFactory _emf;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
+ _debug = "true".equalsIgnoreCase(config.getInitParameter("debug"));
_unit = config.getInitParameter(INIT_PARA_UNIT);
if (_unit == null) {
throw new ServletException(_loc.get("no-persistence-unit-param").toString());
- } else if (findPersistenceUnit()){
+ }
+ boolean standalone = "true".equalsIgnoreCase(config.getInitParameter(INIT_PARA_STANDALONE));
+ if (standalone) {
+ createPersistenceUnit();
+ }
+ if (findPersistenceUnit()) {
config.getServletContext().log(_loc.get("servlet-init", _unit).toString());
} else {
config.getServletContext().log(_loc.get("servlet-not-init", _unit).toString());
@@ -83,19 +96,29 @@ public class JESTServlet extends HttpSer
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ debug(request);
if (findPersistenceUnit()) {
+ JESTContext ctx = new JESTContext(_unit, _emf, request, response);
try {
- JESTContext ctx = new JESTContext(_unit, _emf, request, response);
ctx.execute();
} catch (Exception e) {
- handleError(e, response);
+ handleError(ctx, e);
}
} else {
- handleError(new RuntimeException(_loc.get("no-persistence-unit", _unit).toString()), response);
+ throw new ServletException(_loc.get("no-persistence-unit", _unit).toString());
}
}
- protected boolean findPersistenceUnit() throws ServletException {
+ protected void createPersistenceUnit() throws ServletException {
+ try {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("openjpa.EntityManagerFactoryPool", true);
+ _emf = OpenJPAPersistence.cast(Persistence.createEntityManagerFactory(_unit, map));
+ } catch (Exception e) {
+ throw new ServletException(_loc.get("no-persistence-unit").toString(), e);
+ }
+ }
+ protected boolean findPersistenceUnit() {
if (_emf == null) {
BrokerFactory bf = AbstractBrokerFactory.getPooledFactoryForKey(_unit);
if (bf != null) {
@@ -105,11 +128,33 @@ public class JESTServlet extends HttpSer
return _emf != null;
}
- protected void handleError(Throwable t, HttpServletResponse response) throws IOException {
+ protected void handleError(JPAServletContext ctx, Throwable t) throws IOException {
if (t instanceof ProcessingException) {
- ((ProcessingException)t).printStackTrace(response);
+ ((ProcessingException)t).printStackTrace();
} else {
- new ProcessingException(t).printStackTrace(response);
+ new ProcessingException(ctx, t).printStackTrace();
}
}
+
+ @Override
+ public void destroy() {
+ _emf = null;
+ _unit = null;;
+ }
+
+ private void debug(HttpServletRequest request) {
+ if (!_debug) return;
+ log("-----------------------------------------------------------");
+ log("Request URL = [" + request.getRequestURL() + "]");
+ log("Request URI = [" + request.getRequestURI() + "]");
+ log("Servlet Path = [" + request.getServletPath() + "]");
+ log("Context Path = [" + request.getContextPath() + "]");
+ log("Path Info = [" + request.getPathInfo() + "]");
+ log("Path Translated = [" + request.getPathTranslated() + "]");
+ }
+
+ public void log(String s) {
+ System.err.println(s);
+ super.log(s);
+ }
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JPAServletContext.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JPAServletContext.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JPAServletContext.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JPAServletContext.java Thu Dec 2 11:24:53 2010
@@ -19,6 +19,8 @@
package org.apache.openjpa.persistence.jest;
+import java.net.URI;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -55,6 +57,12 @@ public interface JPAServletContext {
public HttpServletResponse getResponse();
/**
+ * Get the requested URI.
+ * @return
+ */
+ public URI getRequestURI();
+
+ /**
* Resolve the given alias to meta-data of the persistent type.
* @param alias a moniker for the Java type. It can be fully qualified type name or entity name
* or simple name of the actual persistent Java class.
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONObjectFormatter.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONObjectFormatter.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONObjectFormatter.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONObjectFormatter.java Thu Dec 2 11:24:53 2010
@@ -24,8 +24,10 @@ import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
+import java.net.URI;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
@@ -66,7 +68,7 @@ public class JSONObjectFormatter impleme
PrintWriter writer = ctx.getResponse().getWriter();
writer.println(result.toString());
} catch (Exception e) {
- throw new ProcessingException(e);
+ throw new ProcessingException(ctx, e);
}
} else {
throw new RuntimeException(this + " does not know how to encode " + obj);
@@ -74,8 +76,11 @@ public class JSONObjectFormatter impleme
return;
}
- public void writeOut(Collection<OpenJPAStateManager> sms, Metamodel model, PrintWriter writer) throws IOException {
- writer.println(encode(sms,model));
+ public JSON writeOut(Collection<OpenJPAStateManager> sms, Metamodel model, String title, String desc,
+ URI uri, OutputStream out) throws IOException {
+ JSON json = encode(sms,model);
+ out.write(json.toString().getBytes());
+ return json;
}
public JSON encode(Collection<OpenJPAStateManager> sms, Metamodel model) {
@@ -278,21 +283,14 @@ public class JSONObjectFormatter impleme
return writer.toString();
}
- /* (non-Javadoc)
- * @see org.apache.openjpa.persistence.jest.ObjectFormatter#encode(javax.persistence.metamodel.Metamodel)
- */
@Override
public JSON encode(Metamodel model) {
// TODO Auto-generated method stub
return null;
}
- /* (non-Javadoc)
- * @see org.apache.openjpa.persistence.jest.ObjectFormatter#writeOut(javax.persistence.metamodel.Metamodel, java.io.PrintWriter)
- */
@Override
- public void writeOut(Metamodel model, PrintWriter writer) throws IOException {
- // TODO Auto-generated method stub
-
+ public JSON writeOut(Metamodel model, String title, String desc, URI uri, OutputStream out) throws IOException {
+ throw new UnsupportedOperationException();
}
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java Thu Dec 2 11:24:53 2010
@@ -26,7 +26,9 @@ import java.util.List;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.ManagedType;
+import javax.persistence.metamodel.MapAttribute;
import javax.persistence.metamodel.Metamodel;
+import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
import org.apache.openjpa.meta.ClassMetaData;
@@ -39,6 +41,8 @@ import static org.apache.openjpa.persist
*
*/
public class MetamodelHelper {
+ public static final char DASH = '-';
+ public static final char UNDERSCORE = '_';
/**
* Attribute Category makes a finer distinction over PersistentAttributeType declared in
@@ -139,6 +143,33 @@ public class MetamodelHelper {
}
/**
+ * Gets name of the attribute type. For collection and map type attribute, the name is
+ * appended with generic type argument names.
+ * @param attr
+ * @return
+ */
+ public static String getAttributeTypeName(Attribute<?, ?> attr) {
+ StringBuilder name = new StringBuilder(attr.getJavaType().getSimpleName());
+ switch (attr.getPersistentAttributeType()) {
+ case ONE_TO_MANY:
+ case ELEMENT_COLLECTION:
+ name.append("<")
+ .append(((PluralAttribute<?,?,?>)attr).getBindableJavaType().getSimpleName())
+ .append(">");
+ break;
+ case MANY_TO_MANY:
+ name.append("<")
+ .append(((MapAttribute<?,?,?>)attr).getKeyJavaType().getSimpleName())
+ .append(',')
+ .append(((MapAttribute<?,?,?>)attr).getBindableJavaType().getSimpleName())
+ .append(">");
+ break;
+ default:
+ }
+ return name.toString();
+ }
+
+ /**
* Compares attribute by their category and within the same category by name.
*
*/
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ObjectFormatter.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ObjectFormatter.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ObjectFormatter.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ObjectFormatter.java Thu Dec 2 11:24:53 2010
@@ -20,7 +20,9 @@
package org.apache.openjpa.persistence.jest;
import java.io.IOException;
-import java.io.PrintWriter;
+import java.io.OutputStream;
+import java.net.URI;
+import java.text.SimpleDateFormat;
import java.util.Collection;
import javax.persistence.metamodel.Metamodel;
@@ -50,6 +52,7 @@ import org.apache.openjpa.kernel.OpenJPA
*
*/
public interface ObjectFormatter<T> {
+ public static final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy");
/**
* Gets the mime type produced by this formatter.
@@ -83,12 +86,14 @@ public interface ObjectFormatter<T> {
*
* @param objs the collection of objects to be formatted.
* @param model a meta-model of managed types, provided for easier introspection if necessary
+ * @param title TODO
+ * @param desc TODO
+ * @param uri TODO
* @param writer a text-oriented output stream
- *
* @throws IOException
*/
- public void writeOut(Collection<OpenJPAStateManager> objs, Metamodel model,
- PrintWriter writer) throws IOException;
+ public T writeOut(Collection<OpenJPAStateManager> objs, Metamodel model,
+ String title, String desc, URI uri, OutputStream out) throws IOException;
/**
* Encodes the given domain model, then write it into the given output stream.
@@ -98,5 +103,5 @@ public interface ObjectFormatter<T> {
*
* @throws IOException
*/
- public void writeOut(Metamodel model, PrintWriter writer) throws IOException;
+ public T writeOut(Metamodel model, String title, String desc, URI uri, OutputStream out) throws IOException;
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ProcessingException.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ProcessingException.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ProcessingException.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ProcessingException.java Thu Dec 2 11:24:53 2010
@@ -19,17 +19,16 @@
package org.apache.openjpa.persistence.jest;
+import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
+import static org.apache.openjpa.persistence.jest.Constants.MIME_TYPE_XML;
+
import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.HttpURLConnection;
+import java.net.URLDecoder;
import javax.servlet.http.HttpServletResponse;
import org.apache.openjpa.lib.util.Localizer.Message;
-import org.apache.openjpa.persistence.jest.HTMLElement.Tag;
-
-import static org.apache.openjpa.persistence.jest.Constants.*;
-import static java.net.HttpURLConnection.*;
+import org.w3c.dom.Document;
/**
* Specialized RuntimException thrown by JEST commands.
@@ -40,28 +39,32 @@ import static java.net.HttpURLConnection
*/
@SuppressWarnings("serial")
public class ProcessingException extends RuntimeException {
+ private final JPAServletContext ctx;
private final int _errorCode;
- public ProcessingException(Throwable error) {
- this(error, HTTP_INTERNAL_ERROR);
+ public ProcessingException(JPAServletContext ctx, Throwable error) {
+ this(ctx, error, HTTP_INTERNAL_ERROR);
}
- public ProcessingException(Throwable error, int errorCode) {
+ public ProcessingException(JPAServletContext ctx, Throwable error, int errorCode) {
super(error);
+ this.ctx = ctx;
this._errorCode = errorCode;
}
- public ProcessingException(Message message, int errorCode) {
+ public ProcessingException(JPAServletContext ctx, Message message, int errorCode) {
super(message.toString());
+ this.ctx = ctx;
this._errorCode = errorCode;
}
- public ProcessingException(Throwable error, Message message) {
- this(error, message, HTTP_INTERNAL_ERROR);
+ public ProcessingException(JPAServletContext ctx, Throwable error, Message message) {
+ this(ctx, error, message, HTTP_INTERNAL_ERROR);
}
- public ProcessingException(Throwable error, Message message, int errorCode) {
+ public ProcessingException(JPAServletContext ctx, Throwable error, Message message, int errorCode) {
super(message.toString(), error);
+ this.ctx = ctx;
this._errorCode = errorCode;
}
@@ -71,13 +74,19 @@ public class ProcessingException extends
* @param response
* @throws IOException
*/
- public void printStackTrace(HttpServletResponse response) throws IOException {
- response.setContentType(MIME_TYPE_HTML);
- response.setStatus(_errorCode);
- PrintWriter writer = response.getWriter();
- Throwable t = this.getCause() == null ? this : getCause();
- HTMLDocument html = new ExceptionFormatter().createHTML("HTTP Error " + _errorCode, t);
- writer.println(html);
+ public void printStackTrace() {
+ try {
+ HttpServletResponse response = ctx.getResponse();
+ response.setContentType(MIME_TYPE_XML);
+ response.setStatus(_errorCode);
+ Throwable t = this.getCause() == null ? this : getCause();
+ String uri = "URI: " + URLDecoder.decode(ctx.getRequestURI().toString(), "UTF-8");
+ ExceptionFormatter formatter = new ExceptionFormatter();
+ Document xml = formatter.createXML("HTTP Error: " + _errorCode, uri, t);
+ formatter.write(xml, response.getOutputStream(), false);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PropertiesCommand.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PropertiesCommand.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PropertiesCommand.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PropertiesCommand.java Thu Dec 2 11:24:53 2010
@@ -29,6 +29,8 @@ import java.util.Map;
import javax.servlet.http.HttpServletResponse;
+import org.w3c.dom.Document;
+
/**
* Represents configuration properties in HTML.
@@ -37,19 +39,27 @@ import javax.servlet.http.HttpServletRes
*
*/
public class PropertiesCommand extends AbstractCommand {
+ private static final char DOT = '.';
+
+ public PropertiesCommand(JPAServletContext ctx) {
+ super(ctx);
+ }
+ protected int getMaximumArguments() {
+ return 0;
+ }
+
@Override
- public void process(JPAServletContext ctx) throws ProcessingException, IOException {
+ public void process() throws ProcessingException, IOException {
HttpServletResponse response = ctx.getResponse();
- response.setContentType(MIME_TYPE_HTML);
- PrintWriter writer = response.getWriter();
+ response.setContentType(MIME_TYPE_XML);
Map<String,Object> properties = ctx.getPersistenceContext().getProperties();
removeBadEntries(properties);
PropertiesFormatter formatter = new PropertiesFormatter();
String caption = _loc.get("properties-caption", ctx.getPersistenceUnitName()).toString();
- HTMLElement html = formatter.createHTML(caption, "", "", properties);
- writer.println(html);
+ Document xml = formatter.createXML(caption, "", "", properties);
+ formatter.write(xml, response.getOutputStream(), false);
response.setStatus(HttpURLConnection.HTTP_OK);
}
@@ -59,4 +69,9 @@ public class PropertiesCommand extends A
if (keys.next().indexOf(DOT) == -1) keys.remove();
}
}
+
+ @Override
+ protected Format getDefaultFormat() {
+ return Format.xml;
+ }
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PropertiesFormatter.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PropertiesFormatter.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PropertiesFormatter.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PropertiesFormatter.java Thu Dec 2 11:24:53 2010
@@ -22,8 +22,8 @@ package org.apache.openjpa.persistence.j
import java.util.Arrays;
import java.util.Map;
-import org.apache.openjpa.persistence.jest.HTMLElement.Tag;
-import static org.apache.openjpa.persistence.jest.Constants.*;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
/**
* Formats a key-value pair in a HTML Document.
@@ -31,28 +31,19 @@ import static org.apache.openjpa.persist
* @author Pinaki Poddar
*
*/
-class PropertiesFormatter {
- public HTMLDocument createHTML(String title, String tkey, String tvalue, Map<String,Object> properties) {
- HTMLDocument html = new HTMLDocument();
- html.getHead().add(CSS_JEST);
-
- HTMLElement table = new HTMLElement(Tag.table).add(new HTMLElement(Tag.caption).setBody(title));
- HTMLElement header = new HTMLElement(Tag.tr).add(
- new HTMLElement(Tag.th).set(STYLE, "width:35%").setBody(tkey),
- new HTMLElement(Tag.th).set(STYLE, "width:65%").setBody(tvalue));
- table.add(header);
- html.getBody().add(table);
- int i = 0;
+class PropertiesFormatter extends XMLFormatter {
+ public Document createXML(String title, String tkey, String tvalue, Map<String,Object> properties) {
+ Element root = newDocument(Constants.ROOT_ELEMENT_PROPERTIES);
for (Map.Entry<String,Object> entry : properties.entrySet()) {
- HTMLElement row = new HTMLElement(Tag.tr).set(ATTR_CLASS, ++i%2 == 0 ? CSS_EVEN_ROW : CSS_ODD_ROW);
+ Element property = root.getOwnerDocument().createElement("property");
Object value = entry.getValue();
String v = value == null
? Constants.NULL_VALUE
: value.getClass().isArray() ? Arrays.toString((Object[])value) : value.toString();
- table.add(row.add(
- new HTMLElement(Tag.td).setBody(entry.getKey()),
- new HTMLElement(Tag.td).setBody(v)));
+ property.setAttribute(Constants.ATTR_PROPERTY_KEY, entry.getKey());
+ property.setAttribute(Constants.ATTR_PROPERTY_VALUE, v);
+ root.appendChild(property);
}
- return html;
+ return root.getOwnerDocument();
}
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PrototypeFactory.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PrototypeFactory.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PrototypeFactory.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/PrototypeFactory.java Thu Dec 2 11:24:53 2010
@@ -19,44 +19,108 @@
package org.apache.openjpa.persistence.jest;
+import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import org.apache.openjpa.kernel.Filters;
+
/**
* A factory for a specific type of objects registered by a key.
- * The client registers a type indexed by name. The type must have a no-argument constructor.
+ * The client registers a type indexed by name.
* The client can get a new instance of the registered type.
+ * The requested registered type <em>not</em> necessarily have to have a no-arg
+ * constructor. The constructor arguments can be passed during
+ * {@link #newInstance(Class, Object...) new instance} request. Based on the
+ * arguments, a matching constructor, if any, is located and invoked.
+ *
+ * <K> type of key for this registry
+ * <T> base type of the objects to construct
*
* @author Pinaki Poddar
*
*/
-public class PrototypeFactory<T> {
- private Map<String, Class<? extends T>> _registry = new TreeMap<String, Class<? extends T>>();
+public class PrototypeFactory<K,T> {
+ private Map<K, Class<? extends T>> _registry = new TreeMap<K, Class<? extends T>>();
/**
- * Register
- * @param key
- * @param prototype
+ * Register the given class with the given key.
+ *
+ * @param key a non-null key.
+ * @param prototype a type.
*/
- public void register(String key, Class<? extends T> prototype) {
+ public void register(K key, Class<? extends T> prototype) {
_registry.put(key, prototype);
}
- public T newInstance(String name) {
- return _registry.containsKey(name) ? newInstance(_registry.get(name)) : null;
+ /**
+ * Create a new instance of the type {@linkplain #register(Object, Class) registered} before
+ * with the given key, if any.
+ * The given arguments are used to identify a constructor of the registered type and
+ * passed to the constructor of the registered type.
+ *
+ * @param key a key to identify a registered type.
+ * @param args arguments to pass to the constructor of the type.
+ *
+ * @return null if no type has been registered against the given key.
+ */
+ public T newInstance(K key, Object... args) {
+ return _registry.containsKey(key) ? newInstance(_registry.get(key), args) : null;
}
- public Set<String> getRegisteredKeys() {
+ /**
+ * Gets the keys registered in this factory.
+ *
+ * @return immutable set of registered keys.
+ */
+ public Set<K> getRegisteredKeys() {
return Collections.unmodifiableSet(_registry.keySet());
}
- private T newInstance(Class<? extends T> type) {
+ private T newInstance(Class<? extends T> type, Object... args) {
try {
- return type.newInstance();
+ return findConstructor(type, getConstructorParameterTypes(args)).newInstance(args);
} catch (Exception e) {
throw new RuntimeException();
}
}
+
+ Class<?>[] getConstructorParameterTypes(Object... args) {
+ if (args == null || args.length == 0) {
+ return new Class<?>[0];
+ }
+ Class<?>[] types = new Class<?>[args.length];
+ for (int i = 0; i < args.length; i++) {
+ types[i] = args[i] == null ? Object.class : args[i].getClass();
+ }
+ return types;
+ }
+
+ /**
+ * Finds a constructor of the given class with given argument types.
+ */
+ Constructor<? extends T> findConstructor(Class<? extends T> cls, Class<?>[] types) {
+ try {
+ return cls.getConstructor(types);
+ } catch (Exception e) {
+ Constructor<?>[] constructors = cls.getConstructors();
+ for (Constructor<?> cons : constructors) {
+ Class<?>[] paramTypes = cons.getParameterTypes();
+ boolean match = false;
+ if (paramTypes.length == types.length) {
+ for (int i = 0; i < paramTypes.length; i++) {
+ match = paramTypes[i].isAssignableFrom(Filters.wrap(types[i]));
+ if (!match)
+ break;
+ }
+ }
+ if (match) {
+ return (Constructor<? extends T>)cons;
+ }
+ }
+ }
+ throw new RuntimeException();//_loc.get("fill-ctor-none", cls, Arrays.toString(types)).getMessage());
+ }
}
Modified: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/QueryCommand.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/QueryCommand.java?rev=1041330&r1=1041329&r2=1041330&view=diff
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/QueryCommand.java (original)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/QueryCommand.java Thu Dec 2 11:24:53 2010
@@ -41,6 +41,10 @@ class QueryCommand extends AbstractComma
QUALIFIER_FORMAT, QUALIFIER_PLAN, QUALIFIER_NAMED, QUALIFIER_SINGLE,
QUALIFIER_FIRSTRESULT, QUALIFIER_MAXRESULT);
+ public QueryCommand(JPAServletContext ctx) {
+ super(ctx);
+ }
+
@Override
protected Collection<String> getMandatoryArguments() {
return _mandatoryArgs;
@@ -56,7 +60,7 @@ class QueryCommand extends AbstractComma
}
@Override
- public void process(JPAServletContext ctx) throws ProcessingException {
+ public void process() throws ProcessingException {
String spec = getMandatoryArgument(ARG_QUERY);
try {
EntityManager em = ctx.getPersistenceContext();
@@ -70,12 +74,14 @@ class QueryCommand extends AbstractComma
for (Map.Entry<String, String> entry : args.entrySet()) {
query.setParameter(entry.getKey(), entry.getValue());
}
- getObjectFormatter(ctx)
+ getObjectFormatter()
.writeOut(toStateManager(isBooleanQualifier(QUALIFIER_SINGLE)
? Collections.singleton(query.getSingleResult()) : query.getResultList()),
- em.getMetamodel(), ctx.getResponse().getWriter());
+ em.getMetamodel(),
+ _loc.get("query-title").toString(), _loc.get("query-desc").toString(), ctx.getRequestURI(),
+ ctx.getResponse().getOutputStream());
} catch (Exception e) {
- throw new ProcessingException(e, _loc.get("query-execution-error", spec));
+ throw new ProcessingException(ctx, e, _loc.get("query-execution-error", spec));
}
}
}
Added: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java
URL: http://svn.apache.org/viewvc/openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java?rev=1041330&view=auto
==============================================================================
--- openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java (added)
+++ openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java Thu Dec 2 11:24:53 2010
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.openjpa.persistence.jest;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.Arrays;
+
+/**
+ * Reads from an input stream and writes to an output stream after replacing matched tokens
+ * by their counterpart.
+ *
+ *
+ * @author Pinaki Poddar
+ *
+ */
+public class TokenReplacedStream {
+ /**
+ * Read the given input stream and replaces the tokens as it reads. The replaced stream is written to the
+ * given output stream.
+ *
+ * @param in a non-null input stream
+ * @param out a character oriented writer
+ * @param replacements an even number of Strings. Any occurrence of the even-indexed i-th String in the
+ * input stream will be replaced by the (i+1)-th String in the output writer.
+ */
+ public void replace(InputStream in, Writer out, String... prs) throws IOException {
+ if (prs.length%2 != 0)
+ throw new IllegalArgumentException("Even number of pattern/string pairs: " + Arrays.toString(prs)
+ + ". Must be even number of arguments.");
+ Pattern[] patterns = new Pattern[prs.length/2];
+ for (int i = 0; i < prs.length; i += 2) {
+ patterns[i/2] = new Pattern(prs[i], prs[i+1]);
+ }
+
+ StringBuilder tmp = new StringBuilder();
+ for (int c = 0; (c = in.read()) != -1;) {
+ int cursor = match((char)c, patterns);
+ if (cursor < 0) { // no pattern recognized at all
+ if (tmp.length() > 0) { // append partial match then discard partial memory
+ for (int j = 0; j < tmp.length(); j++) {
+ out.write(tmp.charAt(j));
+ }
+ tmp.delete(0, tmp.length());
+ }
+ out.write((char)c); // directly output
+ } else {
+ Pattern p = matched(patterns); // has any pattern matched completely
+ if (p != null) { // a pattern matched completely
+ char[] replace = p.replace().toCharArray();
+ for (int j = 0; j < replace.length; j++) {
+ out.write(replace[j]);
+ }
+ reset(patterns);
+ tmp.delete(0, tmp.length());
+ } else {
+ tmp.append((char)c); // remember partial match
+ }
+ }
+ }
+ }
+
+ /**
+ * Match the given character to all patterns and return the index of highest match.
+ * @param c a character to match
+ * @param patterns an array of patterns
+ * @return -1 if character matched no pattern
+ */
+ int match(char c, Pattern...patterns) {
+ if (patterns == null)
+ return -1;
+ int result = -1;
+ for (Pattern p : patterns) {
+ result = Math.max(result, p.match(c));
+ }
+ return result;
+ }
+
+ /**
+ * Gets the pattern if any in matched state
+ * @param patterns
+ * @return
+ */
+ Pattern matched(Pattern...patterns) {
+ if (patterns == null)
+ return null;
+ for (Pattern p : patterns) {
+ if (p.isMatched()) return p;
+ }
+ return null;
+ }
+
+ /**
+ * Resets all the patterns.
+ * @param patterns
+ */
+ void reset(Pattern...patterns) {
+ if (patterns == null)
+ return;
+ for (Pattern p : patterns) {
+ p.reset();
+ }
+ }
+
+ public static class Pattern {
+ private final char[] chars;
+ private final String _replace;
+ private int _cursor;
+
+ /**
+ * Construct a pattern and its replacement.
+ */
+ public Pattern(String s, String replace) {
+ if (s == null || s.length() == 0)
+ throw new IllegalArgumentException("Pattern [" + s + "] can not be empty or null ");
+ if (replace == null)
+ throw new IllegalArgumentException("Replacement [" + replace + "] is null for pattern [" + s + "]");
+ chars = s.toCharArray();
+ _cursor = -1;
+ _replace = replace;
+ }
+
+ /**
+ * Match the given character with the current cursor and advance the matching length.
+ * @param c
+ * @return the matching length. -1 denotes the pattern did not match the character.
+ */
+ public int match(char c) {
+ if (c != chars[++_cursor]) {
+ reset();
+ }
+ return _cursor;
+ }
+
+ /**
+ * Reset the cursor. Subsequent matching will begin at start.
+ */
+ public void reset() {
+ _cursor = -1;
+ }
+
+ /**
+ * Is this pattern matched fully?
+ * A pattern is fully matched when the matching length is equal to the length of the pattern string.
+ */
+ public boolean isMatched() {
+ return _cursor == chars.length-1;
+ }
+
+ /**
+ * Gets the string to be replaced.
+ */
+ public String replace() {
+ return _replace;
+ }
+
+ public String toString() {
+ return new String(chars) + ":" + _cursor;
+ }
+ }
+
+}
Propchange: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: openjpa/sandboxes/jest/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java
------------------------------------------------------------------------------
svn:mime-type = text/plain