openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ppod...@apache.org
Subject svn commit: r1044138 [2/3] - in /openjpa/trunk/openjpa-jest: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/openjpa/ src/main/java/org/apache/openjpa/persistence/ src/main/java/org/apache/openjpa/...
Date Thu, 09 Dec 2010 21:50:49 GMT
Added: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/JSONObjectFormatter.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/JSONObjectFormatter.java?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/JSONObjectFormatter.java (added)
+++ openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/JSONObjectFormatter.java Thu Dec  9 21:50:47 2010
@@ -0,0 +1,296 @@
+/*
+ * 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.BufferedReader;
+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;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.persistence.metamodel.Attribute;
+import javax.persistence.metamodel.Metamodel;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.persistence.meta.Members;
+import static org.apache.openjpa.persistence.jest.Constants.MIME_TYPE_JSON;
+
+/**
+ * Marshals a root instance and its persistent closure as JSON object.
+ * The closure is resolved against the persistence context that contains the root instance.
+ * The JSON format introduces a $id and $ref to address reference that pure JSON does not. 
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class JSONObjectFormatter implements ObjectFormatter<JSON> {
+    
+    public String getMimeType() {
+        return MIME_TYPE_JSON;
+    }
+
+    public void encode(Object obj, JPAServletContext ctx) {
+        if (obj instanceof OpenJPAStateManager) {
+            try {
+                JSON result = encodeManagedInstance((OpenJPAStateManager)obj, 
+                    ctx.getPersistenceContext().getMetamodel());
+                PrintWriter writer = ctx.getResponse().getWriter();
+                writer.println(result.toString());
+            } catch (Exception e) {
+                throw new ProcessingException(ctx, e);
+            }
+        } else {
+            throw new RuntimeException(this + " does not know how to encode " + obj);
+        }
+        return;
+    }
+    
+    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) {
+        return encodeManagedInstances(sms, model);
+    }
+    
+    /**
+     * Encodes the given managed instance into a new XML element as a child of the given parent node.
+     * 
+     * @param sm a managed instance, can be null.
+     * @param parent the parent node to which the new node be attached.
+     */
+    private JSON encodeManagedInstance(final OpenJPAStateManager sm, Metamodel model) {
+        return encodeManagedInstance(sm, new HashSet<OpenJPAStateManager>(), 0, false, model);
+    }
+    
+    private JSON encodeManagedInstances(final Collection<OpenJPAStateManager> sms, Metamodel model) {
+        JSONObject.Array result = new JSONObject.Array();
+        for (OpenJPAStateManager sm : sms) {
+            result.add(encodeManagedInstance(sm, new HashSet<OpenJPAStateManager>(), 0, false, model));
+        }
+        return result;
+    }
+    
+   
+    /**
+     * Encodes the closure of a persistent instance into a XML element.
+     * 
+     * @param sm the managed instance to be encoded. Can be null.
+     * @param parent the parent XML element to which the new XML element be added. Must not be null. Must be
+     * owned by a document. 
+     * @param visited the persistent instances that had been encoded already. Must not be null or immutable.
+     * 
+     * @return the new element. The element has been appended as a child to the given parent in this method.  
+     */
+    private JSONObject encodeManagedInstance(final OpenJPAStateManager sm, final Set<OpenJPAStateManager> visited, 
+        int indent, boolean indentPara, Metamodel model) {
+        if (visited == null) {
+            throw new IllegalArgumentException("null closure for encoder");
+        }
+        if (sm == null) {
+            return null;
+        }
+        
+        boolean ref = !visited.add(sm);
+        JSONObject root =  new JSONObject(typeOf(sm), sm.getObjectId(), ref);;
+        if (ref) {
+            return root;
+        } 
+        
+        BitSet loaded = sm.getLoaded();
+        StoreContext ctx = (StoreContext)sm.getGenericContext();
+        List<Attribute<?, ?>> attrs = MetamodelHelper.getAttributesInOrder(sm.getMetaData(), model);
+            
+        for (int i = 0; i < attrs.size(); i++) {
+            FieldMetaData fmd = ((Members.Member<?, ?>) attrs.get(i)).fmd;
+            if (!loaded.get(fmd.getIndex())) 
+                continue;
+            Object value = sm.fetch(fmd.getIndex());
+            switch (fmd.getDeclaredTypeCode()) {
+                case JavaTypes.BOOLEAN:
+                case JavaTypes.BYTE:
+                case JavaTypes.CHAR:
+                case JavaTypes.DOUBLE:
+                case JavaTypes.FLOAT:
+                case JavaTypes.INT:
+                case JavaTypes.LONG:
+                case JavaTypes.SHORT:
+
+                case JavaTypes.BOOLEAN_OBJ:
+                case JavaTypes.BYTE_OBJ:
+                case JavaTypes.CHAR_OBJ:
+                case JavaTypes.DOUBLE_OBJ:
+                case JavaTypes.FLOAT_OBJ:
+                case JavaTypes.INT_OBJ:
+                case JavaTypes.LONG_OBJ:
+                case JavaTypes.SHORT_OBJ:
+
+                case JavaTypes.BIGDECIMAL:
+                case JavaTypes.BIGINTEGER:
+                case JavaTypes.DATE:
+                case JavaTypes.NUMBER:
+                case JavaTypes.CALENDAR:
+                case JavaTypes.LOCALE:
+                case JavaTypes.STRING:
+                case JavaTypes.ENUM:
+                         root.set(fmd.getName(),value);
+                break;
+                
+                case JavaTypes.PC:
+                    if (value == null) {
+                        root.set(fmd.getName(), null);
+                    } else {
+                        root.set(fmd.getName(),encodeManagedInstance(ctx.getStateManager(value), visited, 
+                            indent+1, false, model)); 
+                    }
+                    break;
+                    
+                case JavaTypes.ARRAY:
+                    Object[] values = (Object[])value;
+                    value = Arrays.asList(values);
+                // no break;
+                case JavaTypes.COLLECTION:
+                    if (value == null) {
+                        root.set(fmd.getName(), null);
+                        break;
+                    }
+                    Collection<?> members = (Collection<?>)value;
+                    JSONObject.Array array = new JSONObject.Array();
+                    root.set(fmd.getName(), array);
+                    if (members.isEmpty()) {
+                        break;
+                    }
+                    boolean basic = fmd.getElement().getTypeMetaData() == null;
+                    for (Object o : members) {
+                        if (o == null) {
+                            array.add(null);
+                        } else {
+                            if (basic) {
+                                array.add(o);
+                            } else {
+                                array.add(encodeManagedInstance(ctx.getStateManager(o), visited, indent+1, true, 
+                                    model));
+                            }
+                        }
+                    }
+                    break;
+                case JavaTypes.MAP:
+                    if (value == null) {
+                        root.set(fmd.getName(), null);
+                        break;
+                    }
+                    Set<Map.Entry> entries = ((Map)value).entrySet();
+                    JSONObject.KVMap map = new JSONObject.KVMap();
+                    root.set(fmd.getName(), map);
+                    if (entries.isEmpty()) {
+                        break;
+                    }
+                    
+                    boolean basicKey   = fmd.getElement().getTypeMetaData() == null;
+                    boolean basicValue = fmd.getValue().getTypeMetaData() == null;
+                    for (Map.Entry<?,?> e : entries) {
+                        Object k = e.getKey();
+                        Object v = e.getValue();
+                        if (!basicKey) {
+                            k = encodeManagedInstance(ctx.getStateManager(k), visited, indent+1, true, model);
+                        }
+                        if (!basicValue) {
+                            v = encodeManagedInstance(ctx.getStateManager(e.getValue()), visited, 
+                                indent+1, false, model);
+                        }
+                        map.put(k,v);
+                    }
+                    break;
+                    
+                case JavaTypes.INPUT_STREAM:
+                case JavaTypes.INPUT_READER:
+                    root.set(fmd.getName(), streamToString(value));
+                    break;
+                    
+                case JavaTypes.PC_UNTYPED:
+                case JavaTypes.OBJECT:
+                case JavaTypes.OID:
+                    root.set(fmd.getName(), "***UNSUPPORTED***");
+            }
+        }
+        return root;
+    }
+    
+    
+    String typeOf(OpenJPAStateManager sm) {
+        return sm.getMetaData().getDescribedType().getSimpleName();
+    }
+    
+    
+    /**
+     * Convert the given stream (either an InutStream or a Reader) to a String
+     * to be included in CDATA section of a XML document.
+     * 
+     * @param value the field value to be converted. Can not be null 
+     * @return
+     */
+    String streamToString(Object value) {
+        Reader reader = null;
+        if (value instanceof InputStream) {
+            reader = new BufferedReader(new InputStreamReader((InputStream)value));
+        } else if (value instanceof Reader) {
+            reader = (Reader)value;
+        } else {
+            throw new RuntimeException();
+        }
+        CharArrayWriter writer = new CharArrayWriter();
+        try {
+            for (int c; (c = reader.read()) != -1;) {
+                writer.write(c);
+            }
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+        return writer.toString();
+    }
+
+    @Override
+    public JSON encode(Metamodel model) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public JSON writeOut(Metamodel model, String title, String desc, URI uri, OutputStream out) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+}

Propchange: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/JSONObjectFormatter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java (added)
+++ openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java Thu Dec  9 21:50:47 2010
@@ -0,0 +1,187 @@
+/*
+ * 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.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+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;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.persistence.meta.Members;
+import static org.apache.openjpa.persistence.jest.Constants.*;
+
+/**
+ * @author Pinaki Poddar
+ *
+ */
+public class MetamodelHelper {
+    public static final char DASH = '-';
+    public static final char UNDERSCORE = '_';
+    
+    /**
+     * Attribute Category makes a finer distinction over PersistentAttributeType declared in
+     * {@link Attribute.PersistentAttributeType} such as id, version, lob or enum.
+     * <br>
+     * <b>Important</b>: The name of the enumerated elements is important because 
+     * a) some of these names are same as in Attribute.PersistentAttributeType enumeration 
+     * b) names are used by XML serialization with underscores replaced by dash and decapitalized
+     *
+     */
+    public static enum AttributeCategory {
+        ID, VERSION, BASIC, ENUM, EMBEDDED, LOB, 
+        ONE_TO_ONE, MANY_TO_ONE, ONE_TO_MANY, ELEMENT_COLLECTION, MANY_TO_MANY
+    }
+    
+    public static List<Attribute<?,?>> getAttributesInOrder(Class<?> cls, Metamodel model) {
+        return getAttributesInOrder(model.managedType(cls));
+    }
+    
+    public static List<Attribute<?,?>> getAttributesInOrder(ClassMetaData meta, Metamodel model) {
+        return getAttributesInOrder(meta.getDescribedType(), model);
+    }
+    
+    /**
+     * Gets the attributes of the given type in defined order.
+     * @param type
+     * @return
+     */
+    public static List<Attribute<?,?>> getAttributesInOrder(ManagedType<?> type) {
+        List<Attribute<?,?>> list = new ArrayList<Attribute<?,?>>(type.getAttributes());
+        Collections.sort(list, new AttributeComparator());
+        return list;
+    }
+
+    public static boolean isId(Attribute<?,?> a) {
+        if (a instanceof SingularAttribute)
+            return ((SingularAttribute<?,?>)a).isId();
+        return false;
+    }
+    
+    public static boolean isVersion(Attribute<?,?> a) {
+        if (a instanceof SingularAttribute)
+            return ((SingularAttribute<?,?>)a).isVersion();
+        return false;
+    }
+    
+    public static boolean isEnum(Attribute<?,?> a) {
+        if (a instanceof Members.Member) {
+            int type = ((Members.Member<?,?>)a).fmd.getDeclaredTypeCode();
+            return type == JavaTypes.ENUM;
+        }
+        return false;
+    }
+    
+    public static boolean isLob(Attribute<?,?> a) {
+        if (a instanceof Members.Member) {
+            int type = ((Members.Member<?,?>)a).fmd.getDeclaredTypeCode();
+            return type == JavaTypes.INPUT_READER || type == JavaTypes.INPUT_STREAM;
+        }
+        return false;
+    }
+
+    /**
+     * Gets a ordinal value of enumerated persistent attribute category.
+     *  
+     * @param attr
+     * @return
+     */
+    public static AttributeCategory getAttributeCategory(Attribute<?,?> attr) {
+        if (isId(attr))
+            return AttributeCategory.ID;
+        if (isVersion(attr))
+            return AttributeCategory.VERSION;
+        if (isLob(attr))
+            return AttributeCategory.LOB;
+        if (isEnum(attr))
+            return AttributeCategory.ENUM;
+       switch (attr.getPersistentAttributeType()) {
+           case BASIC : 
+               return AttributeCategory.BASIC;
+           case EMBEDDED:
+               return AttributeCategory.EMBEDDED;
+           case ONE_TO_ONE: 
+               return AttributeCategory.ONE_TO_ONE;
+           case MANY_TO_ONE:
+               return AttributeCategory.MANY_TO_ONE;
+           case ONE_TO_MANY:
+           case ELEMENT_COLLECTION:
+               return AttributeCategory.ONE_TO_MANY;
+           case MANY_TO_MANY:
+               return AttributeCategory.MANY_TO_MANY;
+      }
+       throw new RuntimeException(attr.toString());
+    }
+    
+    public static String getTagByAttributeType(Attribute<?, ?> attr) {
+        return getAttributeCategory(attr).name().replace(UNDERSCORE, DASH).toLowerCase();
+    }
+    
+    /**
+     * 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("&lt;")
+                    .append(((PluralAttribute<?,?,?>)attr).getBindableJavaType().getSimpleName())
+                    .append("&gt;");
+                break;
+            case MANY_TO_MANY:
+                name.append("&lt;")
+                .append(((MapAttribute<?,?,?>)attr).getKeyJavaType().getSimpleName())
+                .append(',')
+                .append(((MapAttribute<?,?,?>)attr).getBindableJavaType().getSimpleName())
+                .append("&gt;");
+            break;
+            default:
+        }
+        return name.toString();
+    }
+    
+    /**
+     * Compares attribute by their category and within the same category by name.
+     *
+     */
+    public static class AttributeComparator implements Comparator<Attribute<?,?>> {
+        public int compare(Attribute<?, ?> a1, Attribute<?, ?> a2) {
+            AttributeCategory t1 = getAttributeCategory(a1);
+            AttributeCategory t2 = getAttributeCategory(a2);
+            if (t1.equals(t2)) {
+                return a1.getName().compareTo(a2.getName());
+            } else {
+                return t1.compareTo(t2);
+            }
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/ObjectFormatter.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/ObjectFormatter.java?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/ObjectFormatter.java (added)
+++ openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/ObjectFormatter.java Thu Dec  9 21:50:47 2010
@@ -0,0 +1,107 @@
+/*
+ * 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.OutputStream;
+import java.net.URI;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+
+import javax.persistence.metamodel.Metamodel;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+
+/**
+ * A parameterized interface defines the protocol for converting {@link OpenJPAStateManager managed} persistence 
+ * instances or a persistent {@link Metamodel domain model} into a form suitable for transport to a language-neutral 
+ * client such as an web browser.
+ * <p>
+ * The interface prefers that the resultant resource as a <em>complete</em> representation i.e. all the references 
+ * contained in the resource can be resolved within the same resource itself. As the intended recipient of this 
+ * resource is a remote client, an <em>incomplete</em> resource will require the client to request further for
+ * any (unresolved) reference resulting in a <em>chatty</em> protocol.
+ * <p>
+ * This interface also defines methods for writing the representation into an output stream e.g. 
+ * {@link HttpServletResponse#getOutputStream() response output stream} of a HTTP Servlet.
+ * <p>
+ * Implementation Note:  Each concrete formatter type is registered with {@linkplain PrototypeFactory factory}
+ * that requires the implementation to have a no-argument constructor. 
+ * 
+ * @param <T> the type of encoded output
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public interface ObjectFormatter<T> {
+    public static final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd, yyyy");
+    
+    /**
+     * Gets the mime type produced by this formatter.
+     */
+    public String getMimeType();
+    
+    /**
+     * Encode the {@link Closure persistent closure} of the given collection of managed instances as a 
+     * resource e.g a XML or HTML document or an interactive document with JavaScript or a JSON array.
+     * Exact nature of the output type is the generic parameter of this interface.
+     * 
+     * @param objs a collection of managed instances
+     * @param model domain model
+     * 
+     * @return an encoded object e.g. a XML or HTML Document or a JSON object. 
+     */
+    public T encode(Collection<OpenJPAStateManager> objs, Metamodel model);
+    
+    /**
+     * Encode the given domain model in to a object.
+     * 
+     * @param model a meta-model of managed types
+     * 
+     * @return an encoded object e.g. a XML or HTML Document or a JSON object. 
+     */
+    public T encode(Metamodel model);
+    
+    /**
+     * Encodes the {@link Closure persistent closure} of the given collection of objects, then write it into 
+     * the given output stream. 
+     * 
+     * @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 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.
+     * 
+     * @param model a meta-model of managed types
+     * @param writer a text-oriented output stream
+     * 
+     * @throws IOException
+     */
+    public T writeOut(Metamodel model, String title, String desc, URI uri, OutputStream out) throws IOException;
+}

Propchange: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/ObjectFormatter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/ProcessingException.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/ProcessingException.java?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/ProcessingException.java (added)
+++ openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/ProcessingException.java Thu Dec  9 21:50:47 2010
@@ -0,0 +1,97 @@
+/*
+ * 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 java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
+import static org.apache.openjpa.persistence.jest.Constants.MIME_TYPE_XML;
+
+import java.io.IOException;
+import java.net.URLDecoder;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.openjpa.lib.util.Localizer.Message;
+import org.w3c.dom.Document;
+
+/**
+ * Specialized RuntimException thrown by JEST commands.
+ * The exception can be serialized to the output stream of a HTTP Servlet response as a HTML page.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+@SuppressWarnings("serial")
+public class ProcessingException extends RuntimeException {
+    private final JPAServletContext ctx;
+    private final int _errorCode;
+    
+    public ProcessingException(JPAServletContext ctx, Throwable error) {
+        this(ctx, error, HTTP_INTERNAL_ERROR);
+    }
+    
+    public ProcessingException(JPAServletContext ctx, Throwable error, int errorCode) {
+        super(error);
+        this.ctx = ctx;
+        this._errorCode = errorCode;
+    }
+
+    public ProcessingException(JPAServletContext ctx, Message message, int errorCode) {
+        super(message.toString());
+        this.ctx = ctx;
+        this._errorCode = errorCode;
+    }
+    
+    public ProcessingException(JPAServletContext ctx, Throwable error, Message message) {
+        this(ctx, error, message, HTTP_INTERNAL_ERROR);
+    }
+    
+    public ProcessingException(JPAServletContext ctx, Throwable error, Message message, int errorCode) {
+        super(message.toString(), error);
+        this.ctx = ctx;
+        this._errorCode = errorCode;
+    }
+    
+    /**
+     * Prints the stack trace in a HTML format on the given response output stream.
+     * 
+     * @param response
+     * @throws IOException
+     */
+    public void printStackTrace() {
+        HttpServletResponse response = ctx.getResponse();
+        response.setContentType(MIME_TYPE_XML);
+        response.setStatus(_errorCode);
+
+        String uri = ctx.getRequestURI().toString();
+        try {
+            uri = URLDecoder.decode(uri, "UTF-8");
+        } catch (Exception e) {
+        }
+        Throwable t = this.getCause() == null ? this : getCause();
+        ExceptionFormatter formatter = new ExceptionFormatter();
+        Document xml = formatter.createXML("Request URI: " + uri, t);
+        try {
+            formatter.write(xml, response.getOutputStream());
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("Request URI: " + uri, e);
+        }
+    }
+}

Propchange: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/ProcessingException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PropertiesCommand.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PropertiesCommand.java?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PropertiesCommand.java (added)
+++ openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PropertiesCommand.java Thu Dec  9 21:50:47 2010
@@ -0,0 +1,77 @@
+/*
+ * 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.*;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.w3c.dom.Document;
+
+
+/**
+ * Represents configuration properties in HTML.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+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() throws ProcessingException, IOException {
+        HttpServletResponse response = ctx.getResponse();
+        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();
+        Document xml = formatter.createXML(caption, "", "", properties);
+        formatter.write(xml, response.getOutputStream());
+        response.setStatus(HttpURLConnection.HTTP_OK);
+    }
+    
+    private void removeBadEntries(Map<String,Object> map) {
+        Iterator<String> keys = map.keySet().iterator();
+        for (; keys.hasNext();) {
+            if (keys.next().indexOf(DOT) == -1) keys.remove();
+        }
+    }
+
+    @Override
+    protected Format getDefaultFormat() {
+        return Format.xml;
+    }
+}

Propchange: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PropertiesCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PropertiesFormatter.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PropertiesFormatter.java?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PropertiesFormatter.java (added)
+++ openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PropertiesFormatter.java Thu Dec  9 21:50:47 2010
@@ -0,0 +1,49 @@
+/*
+ * 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.util.Arrays;
+import java.util.Map;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Formats a key-value pair in a HTML Document.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+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()) {
+            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();
+                     property.setAttribute(Constants.ATTR_PROPERTY_KEY, entry.getKey());
+                     property.setAttribute(Constants.ATTR_PROPERTY_VALUE, v);
+            root.appendChild(property);
+        }
+        return root.getOwnerDocument();
+    }
+}

Propchange: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PropertiesFormatter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PrototypeFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PrototypeFactory.java?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PrototypeFactory.java (added)
+++ openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PrototypeFactory.java Thu Dec  9 21:50:47 2010
@@ -0,0 +1,126 @@
+/*
+ * 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.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 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<K,T> {
+    private Map<K, Class<? extends T>> _registry = new TreeMap<K, Class<? extends T>>();
+    
+    /**
+     * Register the given class with the given key.
+     * 
+     * @param key a non-null key.
+     * @param prototype a type.
+     */
+    public void register(K key, Class<? extends T> prototype) {
+        _registry.put(key, prototype);
+    }
+    
+    /**
+     * 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;
+    }
+    
+    /**
+     * 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, Object... args) {
+        try {
+            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());
+    }
+}

Propchange: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/PrototypeFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/QueryCommand.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/QueryCommand.java?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/QueryCommand.java (added)
+++ openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/QueryCommand.java Thu Dec  9 21:50:47 2010
@@ -0,0 +1,98 @@
+/*
+ * 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.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+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;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+
+import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;;
+
+/**
+ * Executes query.
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+class QueryCommand extends AbstractCommand {
+    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, 
+        QUALIFIER_FIRSTRESULT, QUALIFIER_MAXRESULT);
+    
+    public QueryCommand(JPAServletContext ctx) {
+        super(ctx);
+    }
+
+    @Override
+    protected Collection<String> getMandatoryArguments() {
+        return _mandatoryArgs;
+    }
+    
+    @Override
+    protected int getMinimumArguments() {
+        return 0;
+    }
+    
+    protected Collection<String> getValidQualifiers() {
+        return _validQualifiers;
+    }
+
+    @Override
+    public void process() throws ProcessingException {
+        String spec = getMandatoryArgument(ARG_QUERY);
+        OpenJPAEntityManager em = ctx.getPersistenceContext();
+        try {
+            Query query = isBooleanQualifier(QUALIFIER_NAMED) ? em.createNamedQuery(spec) : em.createQuery(spec);
+            if (hasQualifier(QUALIFIER_FIRSTRESULT)) 
+                query.setFirstResult(Integer.parseInt(getQualifier(QUALIFIER_FIRSTRESULT)));
+            if (hasQualifier(QUALIFIER_MAXRESULT)) 
+                query.setMaxResults(Integer.parseInt(getQualifier(QUALIFIER_MAXRESULT)));
+            pushFetchPlan(query);
+            
+            Map<String, String> args = getArguments();
+            for (Map.Entry<String, String> entry : args.entrySet()) {
+                query.setParameter(entry.getKey(), entry.getValue());
+            }
+            getObjectFormatter()
+                .writeOut(toStateManager(isBooleanQualifier(QUALIFIER_SINGLE) 
+                 ? Collections.singleton(query.getSingleResult()) : query.getResultList()), 
+                 em.getMetamodel(), 
+                 _loc.get("query-title").toString(), _loc.get("query-desc").toString(), ctx.getRequestURI(), 
+                 ctx.getResponse().getOutputStream());
+        } catch (ArgumentException e1) {
+            throw new ProcessingException(ctx, e1, _loc.get("query-execution-error", spec), HTTP_BAD_REQUEST);
+        } catch (Exception e) {
+            throw new ProcessingException(ctx, e, _loc.get("query-execution-error", spec));
+        } finally {
+            popFetchPlan(false);
+        }
+    }
+    
+}

Propchange: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/QueryCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java (added)
+++ openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java Thu Dec  9 21:50:47 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/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/TokenReplacedStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/XMLFormatter.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/XMLFormatter.java?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/XMLFormatter.java (added)
+++ openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/XMLFormatter.java Thu Dec  9 21:50:47 2010
@@ -0,0 +1,516 @@
+/*
+ * 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.*;
+
+import java.io.BufferedReader;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.InputStream;
+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;
+
+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 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;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.meta.ClassMetaData;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
+import org.apache.openjpa.meta.ValueMetaData;
+import org.apache.openjpa.persistence.meta.Members;
+import org.apache.openjpa.util.InternalException;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Marshals a root instance and its persistent closure as an XML element.
+ * The closure is resolved against the persistence context that contains the root instance.
+ * The XML document adheres to the <code>jest-instance.xsd</code> schema. 
+ * 
+ * @author Pinaki Poddar
+ *
+ */
+public class XMLFormatter implements ObjectFormatter<Document> {
+    
+    public static final  Schema          _xsd;
+    private static final DocumentBuilder _builder;
+    private static final Transformer     _transformer;
+    private static final String EMPTY_TEXT = " ";
+    
+    static {
+        try {
+            _builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+            _transformer = TransformerFactory.newInstance().newTransformer();
+            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+            InputStream xsd = XMLFormatter.class.getResourceAsStream(JEST_INSTANCE_XSD);
+            _xsd = factory.newSchema(new StreamSource(xsd));
+
+            _transformer.setOutputProperty(OutputKeys.METHOD,     "xml");
+            _transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
+            _transformer.setOutputProperty(OutputKeys.INDENT,     "yes");
+            _transformer.setOutputProperty(OutputKeys.STANDALONE, "no");
+            _transformer.setOutputProperty(OutputKeys.ENCODING,   "UTF-8");
+            _transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    public String getMimeType() {
+        return MIME_TYPE_XML;
+    }    
+    
+    /**
+     * Encodes the closure of given collection of  managed instance into a new XML document 
+     * according to JEST Instance XML Schema.
+     * 
+     * @param sm a collection of managed instances. 
+     * @param parent the parent node to which the new node be attached.
+     */
+    public Document encode(final Collection<OpenJPAStateManager> sms, Metamodel model) {
+        Element root = newDocument(ROOT_ELEMENT_INSTANCE);
+        Closure closure = new Closure(sms);
+        for (OpenJPAStateManager sm : closure) {
+            encodeManagedInstance(sm, root, false, model);
+        }
+        return root.getOwnerDocument();
+    }
+    
+    /**
+     * Encodes the given meta-model into a new XML document according to JEST Domain XML Schema.
+     * 
+     * @param model a persistent domain model. Must not be null.
+     */
+    public Document encode(Metamodel model) {
+        Element root = newDocument(ROOT_ELEMENT_MODEL);
+        for (ManagedType<?> t : model.getManagedTypes()) {
+            encodeManagedType(t, root);
+        }
+        return root.getOwnerDocument();
+    }
+    
+    /**
+     * Create a new document with the given tag as the root element. 
+     * 
+     * @param rootTag the tag of the root element
+     * 
+     * @return the document element of a new document
+     */
+    public Element newDocument(String rootTag) {
+        Document doc = _builder.newDocument();
+        Element root = doc.createElement(rootTag);
+        doc.appendChild(root);
+        String[] nvpairs = new String[] {
+                "xmlns:xsi",                     XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
+//                "xsi:noNamespaceSchemaLocation", JEST_INSTANCE_XSD,
+                ATTR_VERSION,                       "1.0",
+        };
+        for (int i = 0; i < nvpairs.length; i += 2) {
+            root.setAttribute(nvpairs[i], nvpairs[i+1]);
+        }
+        return root;
+    }
+
+    
+    @Override
+    public Document writeOut(Collection<OpenJPAStateManager> objs, Metamodel model, String title, String desc, 
+        URI uri, OutputStream out) throws IOException {
+        Document doc = encode(objs, model);
+        decorate(doc, title, desc, uri);
+        write(doc, out);
+        return doc;
+    }
+    
+    @Override
+    public Document writeOut(Metamodel model, String title, String desc, URI uri, OutputStream out) 
+        throws IOException {
+        Document doc = encode(model);
+        decorate(doc, title, desc, uri);
+        write(doc, out);
+        return doc;
+    }
+    
+    Document decorate(Document doc, String title, String desc, URI 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());
+        Element descElement = doc.createElement(ELEMENT_DESCRIPTION);
+        descElement.setTextContent(desc == null ? NULL_VALUE : desc);
+        root.insertBefore(uriElement, instance);
+        root.insertBefore(descElement, instance);
+        return doc;
+    }
+    
+    public void write(Document doc, OutputStream out) throws IOException {
+        try {
+            _transformer.transform(new DOMSource(doc), new StreamResult(out));
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+    }
+    
+    public void write(Document doc, Writer writer) throws IOException {
+        try {
+            _transformer.transform(new DOMSource(doc), new StreamResult(writer));
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+    }
+    
+    /**
+     * Encodes the closure of a persistent instance into a XML element.
+     * 
+     * @param sm the managed instance to be encoded. Can be null.
+     * @param parent the parent XML element to which the new XML element be added. Must not be null. Must be
+     * owned by a document. 
+     * @param visited the persistent instances that had been encoded already. Must not be null or immutable.
+     * 
+     * @return the new element. The element has been appended as a child to the given parent in this method.  
+     */
+    private Element encodeManagedInstance(final OpenJPAStateManager sm, final Element parent, 
+         boolean isRef, Metamodel model) {
+        if (parent == null)
+            throw new InternalException(_loc.get("format-xml-null-parent"));
+        Document doc = parent.getOwnerDocument();
+        if (doc == null) 
+            throw new InternalException(_loc.get("format-xml-null-doc"));
+        
+        if (sm == null || isRef) {
+            return encodeRef(parent, sm);
+        }
+        Element root = doc.createElement(ELEMENT_INSTANCE);
+        parent.appendChild(root);
+        root.setAttribute(ATTR_ID, ior(sm));
+        Element child = null;
+        BitSet loaded = sm.getLoaded();
+        StoreContext ctx = (StoreContext)sm.getGenericContext();
+        List<Attribute<?, ?>> attrs = MetamodelHelper.getAttributesInOrder(sm.getMetaData(), model);
+        for (int i = 0; i < attrs.size(); child = null, i++) {
+            Members.Member<?, ?> attr = (Members.Member<?, ?>) attrs.get(i);
+            FieldMetaData fmd = attr.fmd;
+            if (!loaded.get(fmd.getIndex())) 
+                continue;
+            String tag = MetamodelHelper.getTagByAttributeType(attr);
+            Object value = sm.fetch(fmd.getIndex());
+            switch (fmd.getDeclaredTypeCode()) {
+                case JavaTypes.BOOLEAN:
+                case JavaTypes.BYTE:
+                case JavaTypes.CHAR:
+                case JavaTypes.DOUBLE:
+                case JavaTypes.FLOAT:
+                case JavaTypes.INT:
+                case JavaTypes.LONG:
+                case JavaTypes.SHORT:
+
+                case JavaTypes.BOOLEAN_OBJ:
+                case JavaTypes.BYTE_OBJ:
+                case JavaTypes.CHAR_OBJ:
+                case JavaTypes.DOUBLE_OBJ:
+                case JavaTypes.FLOAT_OBJ:
+                case JavaTypes.INT_OBJ:
+                case JavaTypes.LONG_OBJ:
+                case JavaTypes.SHORT_OBJ:
+
+                case JavaTypes.BIGDECIMAL:
+                case JavaTypes.BIGINTEGER:
+                case JavaTypes.DATE:
+                case JavaTypes.NUMBER:
+                case JavaTypes.CALENDAR:
+                case JavaTypes.LOCALE:
+                case JavaTypes.STRING:
+                case JavaTypes.ENUM:
+                child = doc.createElement(tag);
+                child.setAttribute(ATTR_NAME, fmd.getName());
+                if (value == null) {
+                    encodeNull(child);
+                } else { 
+                    encodeBasic(child, value, fmd.getDeclaredType());
+                }
+                break;
+                
+                case JavaTypes.OID:
+                    child = doc.createElement(ELEMENT_REF);
+                    child.setAttribute(ATTR_NAME, fmd.getName());
+                    if (value == null) {
+                        encodeNull(child);
+                    } else { 
+                        encodeBasic(child, value, fmd.getDeclaredType());
+                    }
+                    break;
+                    
+                case JavaTypes.PC:
+                    child = doc.createElement(tag);
+                    child.setAttribute(ATTR_NAME, fmd.getName());
+                    child.setAttribute(ATTR_TYPE, typeOf(fmd));
+                    OpenJPAStateManager other = ctx.getStateManager(value);
+                    encodeManagedInstance(other, child, true, model);
+                    break;
+                    
+                case JavaTypes.ARRAY:
+                    Object[] values = (Object[])value;
+                    value = Arrays.asList(values);
+                // no break;
+                case JavaTypes.COLLECTION:
+                    child = doc.createElement(tag);
+                    child.setAttribute(ATTR_NAME, fmd.getName());
+                    child.setAttribute(ATTR_TYPE, typeOf(fmd));
+                    child.setAttribute(ATTR_MEMBER_TYPE, typeOf(fmd.getElement().getDeclaredType()));
+                    if (value == null) {
+                        encodeNull(child);
+                        break;
+                    }
+                    Collection<?> members = (Collection<?>)value;
+                    boolean basic = fmd.getElement().getTypeMetaData() == null;
+                    for (Object o : members) {
+                        Element member = doc.createElement(ELEMENT_MEMBER);
+                        child.appendChild(member);
+                        if (o == null) {
+                            encodeNull(member);
+                        } else {
+                            if (basic) {
+                                encodeBasic(member, o, o.getClass());
+                            } else {
+                                encodeManagedInstance(ctx.getStateManager(o), member, true, model);
+                            }
+                        }
+                    }
+                    break;
+                case JavaTypes.MAP:
+                    child = doc.createElement(tag);
+                    child.setAttribute(ATTR_NAME, fmd.getName());
+                    child.setAttribute(ATTR_TYPE, typeOf(fmd));
+                    child.setAttribute(ATTR_KEY_TYPE, typeOf(fmd.getElement().getDeclaredType()));
+                    child.setAttribute(ATTR_VALUE_TYPE, typeOf(fmd.getValue().getDeclaredType()));
+                    if (value == null) {
+                        encodeNull(child);
+                        break;
+                    }
+                    Set<Map.Entry> entries = ((Map)value).entrySet();
+                    boolean basicKey   = fmd.getElement().getTypeMetaData() == null;
+                    boolean basicValue = fmd.getValue().getTypeMetaData() == null;
+                    for (Map.Entry<?,?> e : entries) {
+                        Element entry = doc.createElement(ELEMENT_ENTRY);
+                        Element entryKey = doc.createElement(ELEMENT_ENTRY_KEY);
+                        Element entryValue = doc.createElement(ELEMENT_ENTRY_VALUE);
+                        entry.appendChild(entryKey);
+                        entry.appendChild(entryValue);
+                        child.appendChild(entry);
+                        if (e.getKey() == null) {
+                            encodeNull(entryKey);
+                        } else {
+                            if (basicKey) {
+                                encodeBasic(entryKey, e.getKey(), e.getKey().getClass());
+                            } else {
+                                encodeManagedInstance(ctx.getStateManager(e.getKey()), entryKey, true, model);
+                            }
+                        }
+                        if (e.getValue() == null) {
+                            encodeNull(entryValue);
+                        } else {
+                            if (basicValue) {
+                                encodeBasic(entryValue, e.getValue(), e.getValue().getClass());
+                            } else {
+                                encodeManagedInstance(ctx.getStateManager(e.getValue()), entryValue, true, model);
+                            }
+                        }
+                    }
+                    break;
+                    
+                case JavaTypes.INPUT_STREAM:
+                case JavaTypes.INPUT_READER:
+                    child = doc.createElement(tag);
+                    child.setAttribute(ATTR_NAME, fmd.getName());
+                    child.setAttribute(ATTR_TYPE, typeOf(fmd));
+                    if (value == null) {
+                        encodeNull(child);
+                    } else { 
+                        CDATASection data = doc.createCDATASection(streamToString(value));
+                        child.appendChild(data);
+                    }
+                    break;
+                    
+                case JavaTypes.PC_UNTYPED:
+                case JavaTypes.OBJECT:
+                    System.err.println("Not handled " + fmd.getName() + " of type " + fmd.getDeclaredType());
+            }
+            
+            if (child != null) {
+                root.appendChild(child);
+            }
+        }
+        return root;
+    }
+    
+    /**
+     * Sets the given value element as null. The <code>null</code> attribute is set to true.
+     * 
+     * @param element the XML element to be set
+     */
+    private void encodeNull(Element element) {
+        element.setAttribute(ATTR_NULL, "true");
+    }
+    
+    private Element encodeRef(Element parent, OpenJPAStateManager sm) {
+        Element ref = parent.getOwnerDocument().createElement(sm == null ? ELEMENT_NULL_REF : ELEMENT_REF);
+        if (sm != null)
+            ref.setAttribute(ATTR_ID, ior(sm));
+     // IMPORTANT: for xml transformer not to omit the closing tag, otherwise dojo is confused
+        ref.setTextContent(EMPTY_TEXT); 
+        parent.appendChild(ref);
+        return ref;
+    }
+    
+    
+    /**
+     * Sets the given value element. The <code>type</code> is set to the given runtime type.
+     * String form of the given object is set as the text content. 
+     * 
+     * @param element the XML element to be set
+     * @param obj value of the element. Never null.
+     */
+    private void encodeBasic(Element element, Object obj, Class<?> runtimeType) {
+        element.setAttribute(ATTR_TYPE, typeOf(runtimeType));
+        if (obj instanceof Date)
+            element.setTextContent(dateFormat.format(obj));
+        else 
+            element.setTextContent(obj == null ? NULL_VALUE : obj.toString());
+    }
+    
+    
+    
+    /**
+     * Convert the given stream (either an InutStream or a Reader) to a String
+     * to be included in CDATA section of a XML document.
+     * 
+     * @param value the field value to be converted. Can not be null 
+     * @return
+     */
+    private String streamToString(Object value) {
+        Reader reader = null;
+        if (value instanceof InputStream) {
+            reader = new BufferedReader(new InputStreamReader((InputStream)value));
+        } else if (value instanceof Reader) {
+            reader = (Reader)value;
+        } else {
+            throw new RuntimeException();
+        }
+        CharArrayWriter writer = new CharArrayWriter();
+        try {
+            for (int c; (c = reader.read()) != -1;) {
+                writer.write(c);
+            }
+        } catch (IOException ex) {
+            throw new RuntimeException(ex);
+        }
+        return writer.toString();
+    }
+    
+    
+    private void encodeManagedType(ManagedType<?> type, Element parent) {
+        Document doc = parent.getOwnerDocument();
+        Element root = doc.createElement(type.getPersistenceType().toString().toLowerCase());
+        parent.appendChild(root);
+        root.setAttribute(ATTR_NAME, type.getJavaType().getSimpleName());
+        List<Attribute<?,?>> attributes = MetamodelHelper.getAttributesInOrder(type);
+        for (Attribute<?,?> a : attributes) {
+            String tag = MetamodelHelper.getTagByAttributeType(a);
+            
+            Element child = doc.createElement(tag);
+            root.appendChild(child);
+            child.setAttribute(ATTR_TYPE, typeOf(a.getJavaType()));
+            if (a instanceof PluralAttribute) {
+                if (a instanceof MapAttribute) {
+                    child.setAttribute(ATTR_KEY_TYPE,   typeOf(((MapAttribute)a).getKeyJavaType()));
+                    child.setAttribute(ATTR_VALUE_TYPE, typeOf(((MapAttribute)a).getBindableJavaType()));
+                } else {
+                    child.setAttribute(ATTR_MEMBER_TYPE, typeOf(((PluralAttribute)a).getBindableJavaType()));
+                }
+            }
+            child.setTextContent(a.getName());
+        }
+    }
+
+    void validate(Document doc) throws Exception {
+        Validator validator = _xsd.newValidator();
+        validator.validate(new DOMSource(doc));
+    }
+    
+    String ior(OpenJPAStateManager sm) {
+        return typeOf(sm) + "-" + sm.getObjectId();
+    }
+    
+    String typeOf(OpenJPAStateManager sm) {
+        return sm.getMetaData().getDescribedType().getSimpleName();
+    }
+    
+    String typeOf(Class<?> cls) {
+        return cls.getSimpleName();
+    }
+    
+    String typeOf(ClassMetaData meta) {
+        return meta.getDescribedType().getSimpleName();
+    }
+    
+    String typeOf(ValueMetaData vm) {
+        if (vm.getTypeMetaData() == null)
+            return typeOf(vm.getType()); 
+        return typeOf(vm.getTypeMetaData());
+    }
+    
+    String typeOf(FieldMetaData fmd) {
+        return fmd.getType().getSimpleName();
+    }
+}

Propchange: openjpa/trunk/openjpa-jest/src/main/java/org/apache/openjpa/persistence/jest/XMLFormatter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/entity-name.html
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/entity-name.html?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/entity-name.html (added)
+++ openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/entity-name.html Thu Dec  9 21:50:47 2010
@@ -0,0 +1,29 @@
+<!--
+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.
+-->
+
+<html>
+<link href="help.css" type="text/css" rel="stylesheet">
+<body>
+<h3>Entity Name</h3>
+
+Specify simple name of a persistent entity.
+JEST will resolve the name to the fully-qualified name of the entity.
+
+</body>
+</html>
\ No newline at end of file

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/entity-name.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/fetch-plan.html
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/fetch-plan.html?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/fetch-plan.html (added)
+++ openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/fetch-plan.html Thu Dec  9 21:50:47 2010
@@ -0,0 +1,51 @@
+<!--
+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.
+-->
+
+<html>
+<link href="help.css" type="text/css" rel="stylesheet">
+<body>
+<h3>Dynamic Fetch Plan</h3>
+
+Specify one or more named fetch plan. Separate multiple names with comma, e.g.
+<p align="center">
+myPlanA, mYPlanB 
+</p> 
+There are two pre-defined plans named: <b>default</b> and <b>all</b>. The <b>default</b> plan that fetches
+all properties of basic type (i.e. <tt>String, int, Date</tt> etc.) and uni-cardinality relations, are 
+active by default. As the plans are additive, to exclude the default plan, you can specify
+<p align="center">
+myPlanA, -default
+</p> 
+
+
+Fetch Plan determines which properties will be fetched when an entity instance is accessed from the data store.
+A plan can traverse relationship path into other entities at arbitrary depth. By default, when an entity
+is fetched, all properties of basic type (i.e. <tt>String, int, Date</tt> etc.) and uni-cardinality relations are
+fetched. 
+<br>
+JPA specification allows <tt>@Fetch.LAZY</tt> and <tt>@Fetch.EAGER</tt> annotation on persistent properties to control 
+fetch behavior. But only <em>statically</em> i.e. at class definition. 
+<p>
+OpenJPA, on the other hand, provides a far richer syntax and semantics to its user to define the
+properties to be fetched through its dynamic Fetch Plan facility. And, more importantly, these
+fetch plans can be modified <em>dynamically</em> per use case basis.
+<p>
+To learn more aboout Fetch Plan, Refer <a href="http://openjpa.apache.org/documentation.html">OpenJPA documentation</a>.
+</body>
+</html>
\ No newline at end of file

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/fetch-plan.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/query.html
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/query.html?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/query.html (added)
+++ openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/query.html Thu Dec  9 21:50:47 2010
@@ -0,0 +1,32 @@
+<!--
+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.
+-->
+
+<html>
+<link href="help.css" type="text/css" rel="stylesheet">
+<body>
+<h3>JPQL Query</h3>
+
+Specify a JPQL query or name of a pre-defined NamedQuery.
+<br>
+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>
+If using named query, check the Named Query Box.
+</body>
+</html>
\ No newline at end of file

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/query.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/response-format.html
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/response-format.html?rev=1044138&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/response-format.html (added)
+++ openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/response-format.html Thu Dec  9 21:50:47 2010
@@ -0,0 +1,28 @@
+<!--
+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.
+-->
+
+<html>
+<link href="help.css" type="text/css" rel="stylesheet">
+<body>
+<h3>Response Format</h3>
+
+Select the response format as XML or JSON. By default, JEST responses are in XML format.
+
+</body>
+</html>
\ No newline at end of file

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/help/response-format.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/arrow_right.jpg
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/arrow_right.jpg?rev=1044138&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/arrow_right.jpg
------------------------------------------------------------------------------
    svn:mime-type = image/jpeg

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/domain.jpg
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/domain.jpg?rev=1044138&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/domain.jpg
------------------------------------------------------------------------------
    svn:mime-type = image/jpeg

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/find.jpg
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/find.jpg?rev=1044138&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/find.jpg
------------------------------------------------------------------------------
    svn:mime-type = image/jpeg

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/help.jpg
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/help.jpg?rev=1044138&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/help.jpg
------------------------------------------------------------------------------
    svn:mime-type = image/jpeg

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/home.jpg
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/home.jpg?rev=1044138&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/home.jpg
------------------------------------------------------------------------------
    svn:mime-type = image/jpeg

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/jest.jpg
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/jest.jpg?rev=1044138&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/jest.jpg
------------------------------------------------------------------------------
    svn:mime-type = image/jpeg

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/monitor.jpg
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/monitor.jpg?rev=1044138&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/monitor.jpg
------------------------------------------------------------------------------
    svn:mime-type = image/jpeg

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/properties.jpg
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/properties.jpg?rev=1044138&view=auto
==============================================================================
Binary file - no diff available.

Propchange: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/properties.jpg
------------------------------------------------------------------------------
    svn:mime-type = image/jpeg

Added: openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/query2.png
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jest/src/main/resources/org/apache/openjpa/persistence/jest/images/query2.png?rev=1044138&view=auto
==============================================================================
Binary file - no diff available.



Mime
View raw message