OPENJPA-1851: Code clean up + Rearrange constants

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1060139 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2011-01-17 23:54:05 +00:00
parent 01c9608fe6
commit 6259f9a0bb
19 changed files with 218 additions and 150 deletions

View File

@ -22,7 +22,6 @@ package org.apache.openjpa.persistence.jest;
import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
import static org.apache.openjpa.persistence.jest.Constants.QUALIFIER_FORMAT;
import static org.apache.openjpa.persistence.jest.Constants.QUALIFIER_PLAN;
import static org.apache.openjpa.persistence.jest.Constants._loc;
import java.io.IOException;
import java.io.PrintWriter;
@ -41,6 +40,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.kernel.BrokerImpl;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.persistence.FetchPlan;
import org.apache.openjpa.persistence.JPAFacadeHelper;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
@ -53,24 +53,31 @@ import org.apache.openjpa.persistence.OpenJPAQuery;
*
*/
abstract class AbstractCommand implements JESTCommand {
public static final char EQUAL = '=';
public static final String PATH_SEPARATOR = "/";
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;
protected final JPAServletContext _ctx;
private static PrototypeFactory<Format,ObjectFormatter<?>> _formatterFactory =
new PrototypeFactory<Format,ObjectFormatter<?>>();
protected static Localizer _loc = Localizer.forPackage(AbstractCommand.class);
static {
_ff.register(Format.xml, XMLFormatter.class);
_ff.register(Format.json, JSONObjectFormatter.class);
_formatterFactory.register(Format.xml, XMLFormatter.class);
_formatterFactory.register(Format.json, JSONObjectFormatter.class);
}
protected AbstractCommand(JPAServletContext ctx) {
this.ctx = ctx;
_ctx = ctx;
}
public JPAServletContext getExecutionContext() {
return _ctx;
}
public String getMandatoryArgument(String key) {
@ -123,7 +130,7 @@ abstract class AbstractCommand implements JESTCommand {
* The qualifiers and arguments are immutable after parse.
*/
public void parse() throws ProcessingException {
HttpServletRequest request = ctx.getRequest();
HttpServletRequest request = _ctx.getRequest();
String path = request.getPathInfo();
if (path != null) {
path = path.substring(1);
@ -198,27 +205,27 @@ abstract class AbstractCommand implements JESTCommand {
* Called post-parse to validate this command has requisite qualifiers and arguments.
*/
protected void validate() {
HttpServletRequest request = ctx.getRequest();
HttpServletRequest request = _ctx.getRequest();
Collection<String> validQualifiers = getValidQualifiers();
for (String key : _qualifiers.keySet()) {
if (!validQualifiers.contains(key)) {
throw new ProcessingException(ctx,_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(ctx, _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(ctx, _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(),
throw new ProcessingException(_ctx, _loc.get("parse-less-argument", this, _args.keySet(),
getMinimumArguments()), HTTP_BAD_REQUEST);
}
}
@ -245,14 +252,14 @@ abstract class AbstractCommand implements JESTCommand {
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);
throw new ProcessingException(_ctx, _loc.get("format-not-supported", new Object[]{format,
_ctx.getRequest().getPathInfo(), _formatterFactory.getRegisteredKeys()}), HTTP_BAD_REQUEST);
}
}
_formatter = _ff.newInstance(format);
_formatter = _formatterFactory.newInstance(format);
if (_formatter == null) {
throw new ProcessingException(ctx, _loc.get("format-not-supported", new Object[]{format,
ctx.getRequest().getPathInfo(), _ff.getRegisteredKeys()}), HTTP_BAD_REQUEST);
throw new ProcessingException(_ctx, _loc.get("format-not-supported", new Object[]{format,
_ctx.getRequest().getPathInfo(), _formatterFactory.getRegisteredKeys()}), HTTP_BAD_REQUEST);
}
}
return _formatter;
@ -279,7 +286,7 @@ abstract class AbstractCommand implements JESTCommand {
protected void pushFetchPlan(Object target) {
if (!hasQualifier(QUALIFIER_PLAN))
return;
OpenJPAEntityManager em = ctx.getPersistenceContext();
OpenJPAEntityManager em = _ctx.getPersistenceContext();
FetchPlan plan = em.pushFetchPlan();
BrokerImpl broker = (BrokerImpl)JPAFacadeHelper.toBroker(em);
if (target instanceof OpenJPAEntityManager) {
@ -302,7 +309,7 @@ abstract class AbstractCommand implements JESTCommand {
protected void popFetchPlan(boolean finder) {
if (!hasQualifier(QUALIFIER_PLAN))
return;
OpenJPAEntityManager em = ctx.getPersistenceContext();
OpenJPAEntityManager em = _ctx.getPersistenceContext();
BrokerImpl broker = (BrokerImpl)JPAFacadeHelper.toBroker(em);
if (finder) {
broker.setCacheFinderQuery(false);

View File

@ -19,7 +19,6 @@
package org.apache.openjpa.persistence.jest;
import org.apache.openjpa.lib.util.Localizer;
/**
* Static String constants
@ -29,21 +28,10 @@ import org.apache.openjpa.lib.util.Localizer;
*/
public interface Constants {
/**
* Command Qualifiers
* Common Command Qualifiers
*/
public static final String QUALIFIER_FORMAT = "format";
public static final String QUALIFIER_PLAN = "plan";
public static final String QUALIFIER_MAXRESULT = "max";
public static final String QUALIFIER_FIRSTRESULT = "first";
public static final String QUALIFIER_NAMED = "named";
public static final String QUALIFIER_SINGLE = "single";
/**
* Command Arguments
*/
public static final String ARG_QUERY = "q";
public static final String ARG_TYPE = "type";
/**
* Mime Types
@ -54,14 +42,6 @@ public interface Constants {
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_UNIT = "persistence.unit";
public static final String INIT_PARA_STANDALONE = "standalone";
/**
* Dojo Toolkit URL and Themes
@ -123,18 +103,11 @@ public interface Constants {
/**
* JEST resources
*/
// 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";
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 Localizer _loc = Localizer.forPackage(JESTContext.class);
public static final String NULL_VALUE = "null";

View File

@ -24,9 +24,6 @@ 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.
*
@ -53,8 +50,12 @@ class DomainCommand extends AbstractCommand {
}
public void process() throws ProcessingException, IOException {
getObjectFormatter().writeOut(ctx.getPersistenceContext().getMetamodel(),
JPAServletContext ctx = getExecutionContext();
ObjectFormatter<?> formatter = getObjectFormatter();
ctx.getResponse().setContentType(formatter.getMimeType());
formatter.writeOut(ctx.getPersistenceContext().getMetamodel(),
_loc.get("domain-title").toString(), _loc.get("domain-desc").toString(), ctx.getRequestURI(),
ctx.getResponse().getOutputStream());
}
}

View File

@ -18,7 +18,6 @@
*/
package org.apache.openjpa.persistence.jest;
import static org.apache.openjpa.persistence.jest.Constants.*;
import java.io.IOException;
import java.net.HttpURLConnection;
@ -29,8 +28,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
@ -42,6 +39,7 @@ import org.apache.openjpa.util.ApplicationIds;
*
*/
class FindCommand extends AbstractCommand {
private static final String ARG_TYPE = "type";
private static final List<String> _mandatoryArgs = Arrays.asList(ARG_TYPE);
private static final List<String> _validQualifiers = Arrays.asList("format", "plan");
@ -65,6 +63,7 @@ class FindCommand extends AbstractCommand {
@Override
public void process() throws ProcessingException {
JPAServletContext ctx = getExecutionContext();
OpenJPAEntityManager em = ctx.getPersistenceContext();
String type = getMandatoryArgument(ARG_TYPE);
ClassMetaData meta = ctx.resolve(type);

View File

@ -62,31 +62,75 @@ public interface JESTCommand {
*/
public static enum Format {xml, json};
/**
* Get the execution context of this command.
*
* @return the execution context. never null.
*/
public JPAServletContext getExecutionContext();
/**
* Parse the given request to populate qualifiers and parameters of this command.
* A command can interpret and consume certain path segments or parameters of the
* 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
* from the original HTTP request.
*/
public void parse() throws ProcessingException;
/**
* Accessors for this command's arguments and qualifiers.
* @return
* @exception IllegalStateException if accessed prior to parsing.
*/
public Map<String,String> getArguments();
public String getArgument(String key);
public boolean hasArgument(String key);
public Map<String,String> getQualifiers();
public String getQualifier(String key);
public boolean hasQualifier(String key);
/**
* Process the given request and write the output on to the given response in the given context.
* @throws ProcessingException
*
*/
public void process() throws ProcessingException, IOException;
/**
* Get this command's arguments.
*
* @exception IllegalStateException if accessed prior to parsing.
*/
public Map<String,String> getArguments();
/**
* Get the value of this command's argument of the given name.
*
* @return null if the argument does not exist.
*
* @exception IllegalStateException if accessed prior to parsing.
*/
public String getArgument(String key);
/**
* Affirm this command contains an argument of the given name.
*
* @exception IllegalStateException if accessed prior to parsing.
*/
public boolean hasArgument(String key);
/**
* Get this command's qualifiers.
*
* @exception IllegalStateException if accessed prior to parsing.
*/
public Map<String,String> getQualifiers();
/**
* Get the value of this command's qualifier of the given name.
*
* @return null if the qualifier does not exist.
*
* @exception IllegalStateException if accessed prior to parsing.
*/
public String getQualifier(String key);
/**
* Affirm this command contains an qualifier of the given name.
*
* @exception IllegalStateException if accessed prior to parsing.
*/
public boolean hasQualifier(String key);
}

View File

@ -19,18 +19,12 @@
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;
@ -68,6 +62,9 @@ public class JESTContext implements JPAServletContext {
public static final Localizer _loc = Localizer.forPackage(JESTContext.class);
private static final String ONE_YEAR_FROM_NOW;
public static final char QUERY_SEPARATOR = '?';
public static final String CONTEXT_ROOT = "/";
public static final String JEST_TEMPLATE = "jest.html";
/**
* Registers known commands in a {@link PrototypeFactory registry}.
@ -123,17 +120,13 @@ public class JESTContext implements JPAServletContext {
/**
*
*/
public URI getRequestURI() {
public String getRequestURI() {
StringBuffer buf = _request.getRequestURL();
String query = _request.getQueryString();
if (query != null) {
if (!isEmpty(query)) {
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);
}
return buf.toString();
}
@ -236,13 +229,16 @@ public class JESTContext implements JPAServletContext {
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(this, _loc.get("resource-not-found", rsrc), HTTP_NOT_FOUND);
}
}
if (in == null) {
throw new ProcessingException(this, _loc.get("resource-not-found", rsrc), HTTP_NOT_FOUND);
}
}
try {
String mimeType = _request.getSession().getServletContext().getMimeType(rsrc);
if (mimeType == null) {
mimeType = "application/text";
}
_response.setContentType(mimeType);
OutputStream out = _response.getOutputStream();
if (mimeType.startsWith("image/")) {
@ -262,13 +258,7 @@ public class JESTContext implements JPAServletContext {
throw new ProcessingException(this, e, _loc.get("resource-not-found", rsrc), HTTP_NOT_FOUND);
}
}
private void log(String s) {
log((short)-1, s);
}
public void log(short level, String message) {
switch (level) {
case Log.INFO: _log.info(message); break;
@ -291,6 +281,10 @@ public class JESTContext implements JPAServletContext {
return (path == null || CONTEXT_ROOT.equals(path));
}
boolean isEmpty(String s) {
return s == null || s.trim().length() == 0;
}
/**
* 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
@ -320,7 +314,7 @@ public class JESTContext implements JPAServletContext {
"${dojo.theme}", Constants.DOJO_THEME,
};
InputStream in = getClass().getResourceAsStream(Constants.JEST_TEMPLATE);
InputStream in = getClass().getResourceAsStream(JEST_TEMPLATE);
CharArrayWriter out = new CharArrayWriter();
new TokenReplacedStream().replace(in, out, tokens);
_rootResource = out.toString();

View File

@ -19,13 +19,7 @@
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;
@ -36,6 +30,7 @@ import javax.servlet.http.HttpServletResponse;
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 org.apache.openjpa.persistence.OpenJPAPersistence;
@ -67,9 +62,17 @@ import org.apache.openjpa.persistence.OpenJPAPersistence;
*/
@SuppressWarnings("serial")
public class JESTServlet extends HttpServlet {
/**
* Servlet initialization parameter monikers
*/
public static final String INIT_PARA_UNIT = "persistence.unit";
public static final String INIT_PARA_STANDALONE = "standalone";
private String _unit;
private boolean _debug;
private OpenJPAEntityManagerFactory _emf;
protected static Localizer _loc = Localizer.forPackage(JESTServlet.class);
@Override
public void init(ServletConfig config) throws ServletException {
@ -80,6 +83,7 @@ public class JESTServlet extends HttpServlet {
throw new ServletException(_loc.get("no-persistence-unit-param").toString());
}
boolean standalone = "true".equalsIgnoreCase(config.getInitParameter(INIT_PARA_STANDALONE));
System.err.println("Standalone Deployment Mode " + standalone);
if (standalone) {
createPersistenceUnit();
}
@ -111,19 +115,24 @@ public class JESTServlet extends HttpServlet {
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));
System.err.println("Creating Standalone Persistent Unit " + _unit + ":" + _emf);
_emf = OpenJPAPersistence.cast(Persistence.createEntityManagerFactory(_unit));
System.err.println("Created Standalone Persistent Unit " + _unit + ":" + _emf);
} catch (Exception e) {
throw new ServletException(_loc.get("no-persistence-unit").toString(), e);
System.err.println("Can not creating Standalone Persistent Unit " + _unit);
e.printStackTrace();
throw new ServletException(_loc.get("no-persistence-unit-standalone", _unit).toString(), e);
}
}
protected boolean findPersistenceUnit() {
if (_emf == null) {
System.err.println("Discovering auxiliary Persistent Unit " + _unit);
BrokerFactory bf = AbstractBrokerFactory.getPooledFactoryForKey(_unit);
if (bf != null) {
_emf = (OpenJPAEntityManagerFactory)bf.getUserObject(JPAFacadeHelper.EMF_KEY);
}
System.err.println("Discovered auxiliary Persistent Unit " + _unit + ":" + _emf);
}
return _emf != null;
}

View File

@ -19,8 +19,6 @@
package org.apache.openjpa.persistence.jest;
import java.net.URI;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -60,7 +58,7 @@ public interface JPAServletContext {
* Get the requested URI.
* @return
*/
public URI getRequestURI();
public String getRequestURI();
/**
* Resolve the given alias to meta-data of the persistent type.

View File

@ -128,12 +128,19 @@ public class JSONObject implements JSON {
return new StringBuilder().append(QUOTE).append(o.toString()).append(QUOTE);
}
/**
* An array of objects. Members can be JSON too.
*
* @author Pinaki Poddar
*
*/
public static class Array implements JSON {
private List<Object> _members = new ArrayList<Object>();
public void add(Object o) {
_members.add(o);
}
public String toString() {
return asString(0).toString();
}
@ -143,11 +150,11 @@ public class JSONObject implements JSON {
StringBuilder tab = JSONObject.newIndent(indent+1);
for (Object o : _members) {
if (buf.length() > 1) buf.append(MEMBER_SEPARATOR);
buf.append(NEWLINE);
buf.append(NEWLINE).append(tab);
if (o instanceof JSON)
buf.append(tab).append(((JSON)o).asString(indent+1));
buf.append(((JSON)o).asString(indent+1));
else
buf.append(tab).append(o);
buf.append(o);
}
buf.append(NEWLINE)
.append(JSONObject.newIndent(indent))
@ -157,6 +164,13 @@ public class JSONObject implements JSON {
}
}
/**
* A map whose key or value can be JSON.
* A map is encoded as JSON as an array of entries. Each entry is a key value pair separated with :
*
* @author Pinaki Poddar
*
*/
public static class KVMap implements JSON {
private Map<Object,Object> _entries = new LinkedHashMap<Object,Object>();
@ -172,19 +186,21 @@ public class JSONObject implements JSON {
StringBuilder buf = new StringBuilder().append(ARRAY_START);
StringBuilder tab = JSONObject.newIndent(indent+1);
for (Map.Entry<Object, Object> e : _entries.entrySet()) {
if (buf.length()>1) buf.append(MEMBER_SEPARATOR);
buf.append(NEWLINE);
if (buf.length() > 1) buf.append(MEMBER_SEPARATOR);
buf.append(NEWLINE).append(tab);
Object key = e.getKey();
if (key instanceof JSON)
buf.append(tab).append(((JSON)key).asString(indent+1));
else
buf.append(tab).append(key);
if (key instanceof JSON) {
buf.append(((JSON)key).asString(indent+1));
} else {
buf.append(key);
}
buf.append(VALUE_SEPARATOR);
Object value = e.getValue();
if (value instanceof JSON)
if (value instanceof JSON) {
buf.append(((JSON)value).asString(indent+2));
else
} else {
buf.append(value);
}
}
buf.append(NEWLINE)

View File

@ -27,7 +27,6 @@ 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;
@ -77,7 +76,7 @@ public class JSONObjectFormatter implements ObjectFormatter<JSON> {
}
public JSON writeOut(Collection<OpenJPAStateManager> sms, Metamodel model, String title, String desc,
URI uri, OutputStream out) throws IOException {
String uri, OutputStream out) throws IOException {
JSON json = encode(sms,model);
out.write(json.toString().getBytes());
return json;
@ -290,7 +289,7 @@ public class JSONObjectFormatter implements ObjectFormatter<JSON> {
}
@Override
public JSON writeOut(Metamodel model, String title, String desc, URI uri, OutputStream out) throws IOException {
public JSON writeOut(Metamodel model, String title, String desc, String uri, OutputStream out) throws IOException {
throw new UnsupportedOperationException();
}
}

View File

@ -34,7 +34,6 @@ import javax.persistence.metamodel.SingularAttribute;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.persistence.meta.Members;
import static org.apache.openjpa.persistence.jest.Constants.*;
/**
* @author Pinaki Poddar

View File

@ -21,7 +21,6 @@ package org.apache.openjpa.persistence.jest;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Collection;
@ -93,7 +92,7 @@ public interface ObjectFormatter<T> {
* @throws IOException
*/
public T writeOut(Collection<OpenJPAStateManager> objs, Metamodel model,
String title, String desc, URI uri, OutputStream out) throws IOException;
String title, String desc, String uri, OutputStream out) throws IOException;
/**
* Encodes the given domain model, then write it into the given output stream.
@ -103,5 +102,5 @@ public interface ObjectFormatter<T> {
*
* @throws IOException
*/
public T writeOut(Metamodel model, String title, String desc, URI uri, OutputStream out) throws IOException;
public T writeOut(Metamodel model, String title, String desc, String uri, OutputStream out) throws IOException;
}

View File

@ -89,6 +89,7 @@ public class ProcessingException extends RuntimeException {
Document xml = formatter.createXML("Request URI: " + uri, t);
try {
formatter.write(xml, response.getOutputStream());
response.sendError(_errorCode);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Request URI: " + uri, e);

View File

@ -22,7 +22,6 @@ package org.apache.openjpa.persistence.jest;
import static org.apache.openjpa.persistence.jest.Constants.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.util.Iterator;
import java.util.Map;
@ -51,6 +50,7 @@ public class PropertiesCommand extends AbstractCommand {
@Override
public void process() throws ProcessingException, IOException {
JPAServletContext ctx = getExecutionContext();
HttpServletResponse response = ctx.getResponse();
response.setContentType(MIME_TYPE_XML);

View File

@ -26,7 +26,6 @@ import java.util.List;
import java.util.Map;
import static org.apache.openjpa.persistence.jest.Constants.*;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.openjpa.persistence.ArgumentException;
@ -41,6 +40,11 @@ import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;;
*
*/
class QueryCommand extends AbstractCommand {
private static final String ARG_QUERY = "q";
public static final String QUALIFIER_MAXRESULT = "max";
public static final String QUALIFIER_FIRSTRESULT = "first";
public static final String QUALIFIER_NAMED = "named";
public static final String QUALIFIER_SINGLE = "single";
private static final List<String> _mandatoryArgs = Arrays.asList(ARG_QUERY);
private static final List<String> _validQualifiers = Arrays.asList(
QUALIFIER_FORMAT, QUALIFIER_PLAN, QUALIFIER_NAMED, QUALIFIER_SINGLE,
@ -66,6 +70,7 @@ class QueryCommand extends AbstractCommand {
@Override
public void process() throws ProcessingException {
JPAServletContext ctx = getExecutionContext();
String spec = getMandatoryArgument(ARG_QUERY);
OpenJPAEntityManager em = ctx.getPersistenceContext();
try {
@ -94,5 +99,4 @@ class QueryCommand extends AbstractCommand {
popFetchPlan(false);
}
}
}

View File

@ -19,7 +19,28 @@
package org.apache.openjpa.persistence.jest;
import static org.apache.openjpa.persistence.jest.Constants.*;
import static org.apache.openjpa.persistence.jest.Constants.ATTR_ID;
import static org.apache.openjpa.persistence.jest.Constants.ATTR_KEY_TYPE;
import static org.apache.openjpa.persistence.jest.Constants.ATTR_MEMBER_TYPE;
import static org.apache.openjpa.persistence.jest.Constants.ATTR_NAME;
import static org.apache.openjpa.persistence.jest.Constants.ATTR_NULL;
import static org.apache.openjpa.persistence.jest.Constants.ATTR_TYPE;
import static org.apache.openjpa.persistence.jest.Constants.ATTR_VALUE_TYPE;
import static org.apache.openjpa.persistence.jest.Constants.ATTR_VERSION;
import static org.apache.openjpa.persistence.jest.Constants.ELEMENT_DESCRIPTION;
import static org.apache.openjpa.persistence.jest.Constants.ELEMENT_ENTRY;
import static org.apache.openjpa.persistence.jest.Constants.ELEMENT_ENTRY_KEY;
import static org.apache.openjpa.persistence.jest.Constants.ELEMENT_ENTRY_VALUE;
import static org.apache.openjpa.persistence.jest.Constants.ELEMENT_INSTANCE;
import static org.apache.openjpa.persistence.jest.Constants.ELEMENT_MEMBER;
import static org.apache.openjpa.persistence.jest.Constants.ELEMENT_NULL_REF;
import static org.apache.openjpa.persistence.jest.Constants.ELEMENT_REF;
import static org.apache.openjpa.persistence.jest.Constants.ELEMENT_URI;
import static org.apache.openjpa.persistence.jest.Constants.JEST_INSTANCE_XSD;
import static org.apache.openjpa.persistence.jest.Constants.MIME_TYPE_XML;
import static org.apache.openjpa.persistence.jest.Constants.NULL_VALUE;
import static org.apache.openjpa.persistence.jest.Constants.ROOT_ELEMENT_INSTANCE;
import static org.apache.openjpa.persistence.jest.Constants.ROOT_ELEMENT_MODEL;
import java.io.BufferedReader;
import java.io.CharArrayWriter;
@ -29,15 +50,10 @@ import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.URI;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -47,12 +63,10 @@ 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 javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
@ -64,6 +78,7 @@ import javax.xml.validation.Validator;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.StoreContext;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
@ -88,6 +103,7 @@ public class XMLFormatter implements ObjectFormatter<Document> {
private static final DocumentBuilder _builder;
private static final Transformer _transformer;
private static final String EMPTY_TEXT = " ";
protected static Localizer _loc = Localizer.forPackage(XMLFormatter.class);
static {
try {
@ -166,7 +182,7 @@ public class XMLFormatter implements ObjectFormatter<Document> {
@Override
public Document writeOut(Collection<OpenJPAStateManager> objs, Metamodel model, String title, String desc,
URI uri, OutputStream out) throws IOException {
String uri, OutputStream out) throws IOException {
Document doc = encode(objs, model);
decorate(doc, title, desc, uri);
write(doc, out);
@ -174,7 +190,7 @@ public class XMLFormatter implements ObjectFormatter<Document> {
}
@Override
public Document writeOut(Metamodel model, String title, String desc, URI uri, OutputStream out)
public Document writeOut(Metamodel model, String title, String desc, String uri, OutputStream out)
throws IOException {
Document doc = encode(model);
decorate(doc, title, desc, uri);
@ -182,11 +198,11 @@ public class XMLFormatter implements ObjectFormatter<Document> {
return doc;
}
Document decorate(Document doc, String title, String desc, URI uri) {
Document decorate(Document doc, String title, String desc, String uri) {
Element root = doc.getDocumentElement();
Element instance = (Element)root.getElementsByTagName(ELEMENT_INSTANCE).item(0);
Element uriElement = doc.createElement(ELEMENT_URI);
uriElement.setTextContent(uri == null ? NULL_VALUE : uri.toString());
uriElement.setTextContent(uri == null ? NULL_VALUE : uri);
Element descElement = doc.createElement(ELEMENT_DESCRIPTION);
descElement.setTextContent(desc == null ? NULL_VALUE : desc);
root.insertBefore(uriElement, instance);
@ -338,7 +354,7 @@ public class XMLFormatter implements ObjectFormatter<Document> {
encodeNull(child);
break;
}
Set<Map.Entry> entries = ((Map)value).entrySet();
Set<Map.Entry<?,?>> entries = ((Map)value).entrySet();
boolean basicKey = fmd.getElement().getTypeMetaData() == null;
boolean basicValue = fmd.getValue().getTypeMetaData() == null;
for (Map.Entry<?,?> e : entries) {

View File

@ -27,6 +27,14 @@ Specify a JPQL query or name of a pre-defined NamedQuery.
Both queries can accept query bind parameters. The type of the parameters are guessed by JEST
from the string you specify in this web form.
<p>
<b>NOTE:</b> If you use special characters such as '%' in the query, use them as binding parameter value.
For example, <b>do not</b> use query as<br>
<tt>select m from Movie m where m.title like '%CHINA%'</tt>
Instead use<br>
<tt>select m from Movie m where m.title like :title</tt>
<br>
and then set the value of named parameter <tt>title</tt> to <tt>%CHINA%</tt>
<p>
If using named query, check the Named Query Box.
</body>
</html>

View File

@ -281,7 +281,7 @@ function Command_toURI() {
var key = getNodeValue(pair[0]);
var value = getNodeValue(pair[1]);
if (key != null && value != null) {
args = args.concat(args.length == 0 ? '' : '&').concat(key).concat('=').concat(value);
args = args.concat(args.length == 0 ? '' : '&').concat(key).concat('=').concat(escape(value));
}
}
}

View File

@ -22,15 +22,16 @@ servlet-init: JEST Servlet is initialized for "{0}" persistence unit.
servlet-not-init: JEST Servlet can not find "{0}" persistence unit during servlet initialization. \
JEST Servlet will try to locate the unit when a request is to be served.
no-persistence-unit: JEST can not locate the component using persistence unit <b>{0}</b>. This can happen \
for several reasons: \
<OL>the component is not initialized. </OL>\
<OL>the component and JEST servlet do not belong to the same deployment module</OL>\
<OL>the component did not configure the persistence unit for pooling. To enable pooling, \
create the persistence unit with configuration property <code>openjpa.EntityManagerFactoryPool=true</code>.<br> \
The property must be passed to <code>Persistence.createEntityManagerFactory(String unit, Map props)</code> \
with the second <code>Map</code> argument and <em>not</em> via <code>META-INF/persistence.xml</code></OL>.
no-persistence-unit: JEST can not locate the component using persistence unit {0}. This can happen \
for several reasons: \r\n\
a) the component using persistence unit {0} is not initialized. \r\n\
b) the component using persistence unit {0} and JEST servlet do not belong to the same deployment module \r\n\
c) the component did not configure the persistence unit for pooling. To enable pooling, \
create the persistence unit with configuration property openjpa.EntityManagerFactoryPool set to true. \r\n\
The property must be passed to Persistence.createEntityManagerFactory(String unit, Map props) \
with the Map argument and not via META-INF/persistence.xml.
no-persistence-unit-standalone: JEST can not create persistence unit {0} in standalone mode.
resource-not-found: Can not locate resource {0}. <br>This can happen for wrong URI syntax. See \
<A href="http://openjpa.apache.org/jest-syntax.html" target="_blank">JEST URI Help page</A> for correct syntax.