openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeremy Bauer <techhu...@gmail.com>
Subject Re: svn commit: r1028093 [1/2] - JEST...
Date Wed, 27 Oct 2010 22:32:09 GMT
Ditto on the concerns.  Maybe this would be a good opportunity to discuss a
2.1 release date?  That may help guide whether we decide to include large
new features in 2.1 or hold off until 2.x.x and give them more time to brew.

-Jeremy

On Wed, Oct 27, 2010 at 5:11 PM, Kevin Sutter <kwsutter@gmail.com> wrote:

> I have to admit that I was having the same questions/concerns that Donald
> just raised.  I thought we were still in the discussion and experimentation
> phase of this REST work.  Is it really ready for prime time?
>
> Kevin
>
> On Wed, Oct 27, 2010 at 4:58 PM, Donald Woods <dwoods@apache.org> wrote:
>
> > Is this really ready to drop into trunk?
> > And do we really want it in the base openjpa.jar?
> >
> >
> > -Donald
> >
> >
> > On 10/27/10 4:42 PM, ppoddar@apache.org wrote:
> > > Author: ppoddar
> > > Date: Wed Oct 27 20:42:44 2010
> > > New Revision: 1028093
> > >
> > > URL: http://svn.apache.org/viewvc?rev=1028093&view=rev
> > > Log:
> > > OPENJPA-1851: First version of JEST (REST on OpenJPA)
> > >
> > > Added:
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractResponse.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ErrorResponse.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/GETRequest.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ImageResponse.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTRequest.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTResponse.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONEncoder.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Request.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestFactory.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestHandler.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ResourceResponse.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Response.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Server.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ServerContext.java
> >   (with props)
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/XMLEncoder.java
> >   (with props)
> > > Modified:
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
> > >
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java
> > >
> > > Modified:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java?rev=1028093&r1=1028092&r2=1028093&view=diff
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
> > (original)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -45,10 +45,10 @@ import org.apache.openjpa.lib.util.Close
> > >  import org.apache.openjpa.lib.util.Localizer;
> > >  import org.apache.openjpa.persistence.criteria.CriteriaBuilderImpl;
> > >  import org.apache.openjpa.persistence.criteria.OpenJPACriteriaBuilder;
> > > +import org.apache.openjpa.persistence.jest.Server;
> > >  import org.apache.openjpa.persistence.meta.MetamodelImpl;
> > >  import org.apache.openjpa.persistence.query.OpenJPAQueryBuilder;
> > >  import org.apache.openjpa.persistence.query.QueryBuilderImpl;
> > > -import org.apache.openjpa.util.UserException;
> > >
> > >  /**
> > >   * Implementation of {@link EntityManagerFactory} that acts as a
> > > @@ -70,7 +70,8 @@ public class EntityManagerFactoryImpl
> > >      private transient StoreCache _cache = null;
> > >      private transient QueryResultCache _queryCache = null;
> > >      private transient MetamodelImpl _metaModel;
> > > -
> > > +    private transient Server _remoteAccess = null;
> > > +
> > >      /**
> > >       * Default constructor provided for auto-instantiation.
> > >       */
> > > @@ -93,10 +94,11 @@ public class EntityManagerFactoryImpl
> > >
> > >      /**
> > >       * Delegate must be provided before use.
> > > +     * Configures for Remote Access, if appropriate.
> > >       */
> > >      public void setBrokerFactory(BrokerFactory factory) {
> > > -        _factory = new DelegatingBrokerFactory(factory,
> > > -            PersistenceExceptions.TRANSLATOR);
> > > +        _factory = new DelegatingBrokerFactory(factory,
> > PersistenceExceptions.TRANSLATOR);
> > > +        configureRemoteAccess(getConfiguration());
> > >      }
> > >
> > >      public OpenJPAConfiguration getConfiguration() {
> > > @@ -271,6 +273,10 @@ public class EntityManagerFactoryImpl
> > >          if (log.isTraceEnabled()) {
> > >              log.trace(this + ".close() invoked.");
> > >          }
> > > +        if (_remoteAccess != null) {
> > > +            _remoteAccess.stop();
> > > +            _remoteAccess = null;
> > > +        }
> > >          _factory.close();
> > >      }
> > >
> > > @@ -396,4 +402,40 @@ public class EntityManagerFactoryImpl
> > >              }
> > >          }
> > >      }
> > > +
> > > +    /**
> > > +     * Configures this unit for remote access.
> > > +     */
> > > +    protected void configureRemoteAccess(OpenJPAConfiguration conf) {
> > > +        Value value = conf.getValue("RemoteAccess");
> > > +        if (value == null) {
> > > +            return;
> > > +        }
> > > +        String props = value.getString();
> > > +        if (props == null)
> > > +            return;
> > > +        try {
> > > +            _remoteAccess = new Server();
> > > +            _remoteAccess.setContext(this);
> > > +            Configurations.configureInstance(_remoteAccess, conf,
> > props);
> > > +            conf.removeValue(value);
> > > +            if (!_remoteAccess.start()) {
> > > +                _remoteAccess = null;
> > > +            }
> > > +        } catch (Exception ex) {
> > > +            Log log =
> > _factory.getConfiguration().getLog(OpenJPAConfiguration.LOG_RUNTIME);
> > > +            if (log != null) {
> > > +                log.error(_loc.get("remote-start-error"), ex);
> > > +            }
> > > +        }
> > > +    }
> > > +
> > > +    /**
> > > +     * Affirms if this unit is accessible remotely.
> > > +     */
> > > +    public boolean allowsRemoteAccess() {
> > > +        return _remoteAccess != null;
> > > +    }
> > > +
> > > +
> > >  }
> > >
> > > Modified:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java?rev=1028093&r1=1028092&r2=1028093&view=diff
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java
> > (original)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -188,6 +188,7 @@ public class PersistenceProductDerivatio
> > >          conf.metaFactoryPlugin.setAlias(SPEC_JPA.getName(),
> >  PersistenceMetaDataFactory.class.getName());
> > >
> > >          conf.addValue(new EntityManagerFactoryValue());
> > > +        conf.addString("RemoteAccess");
> > >
> > >          conf.readLockLevel.setAlias("optimistic",
> > String.valueOf(MixedLockLevels.LOCK_OPTIMISTIC));
> > >          conf.readLockLevel.setAlias("optimistic-force-increment",
> String
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractResponse.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractResponse.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractResponse.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractResponse.java
> > Wed Oct 27 20:42:44 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 java.io.OutputStream;
> > > +import java.io.PrintStream;
> > > +
> > > +/**
> > > + * Abstract implementation of a stream-based response.
> > > + * Every response is result of a {@linkplain Request} and operates
> > within a {@linkplain ServerContext}.
> > > + * This fact is enforced by the constructor argument of an abstract
> > response.
> > > + * <p>
> > > + * Besides, this implementation provides common utility to write HTTP
> > response or extract useful information
> > > + * from the request.
> > > + *
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +@SuppressWarnings("serial")
> > > +public abstract class AbstractResponse extends PrintStream implements
> > Response {
> > > +    protected final Request _request;
> > > +    protected final ServerContext _ctx;
> > > +
> > > +    /**
> > > +     * Construct a response for the given request and server context.
> > > +     *
> > > +     * @param request the request for this response. Can be null if
> the
> > response is for server error.
> > > +     * @param ctx the processing context
> > > +     * @param out the output stream where the response is targeted.
> > > +     */
> > > +    protected AbstractResponse(Request request, ServerContext ctx,
> > OutputStream out) {
> > > +        super(out);
> > > +        _request = request;
> > > +        _ctx = ctx;
> > > +    }
> > > +
> > > +    /**
> > > +     * Write a HTTP header to the stream.
> > > +     * <br>
> > > +     * The format of HTTP header is <code>key: [value]* NEWLINE</code>
> > > +     *
> > > +     * @param key the key of the header
> > > +     * @param values one of more value of the header fields.
> > > +     */
> > > +    protected void printHeader(String key, String...values) {
> > > +        if (key == null)
> > > +            return;
> > > +        print(key);
> > > +        print(" :");
> > > +        if (values == null || values.length == 0)
> > > +            return;
> > > +        int n = values.length-1;
> > > +        for (int i = 0; i < n-1; i++) {
> > > +            print(values[i]);
> > > +            print(";");
> > > +        }
> > > +        println(values[n]);
> > > +    }
> > > +
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractResponse.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/AbstractResponse.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ErrorResponse.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ErrorResponse.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ErrorResponse.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ErrorResponse.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,68 @@
> > > +/*
> > > + * 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.OutputStream;
> > > +import java.net.HttpURLConnection;
> > > +
> > > +/**
> > > + * A HTTP response for something gone wrong.
> > > + *
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +@SuppressWarnings("serial")
> > > +public class ErrorResponse extends AbstractResponse {
> > > +    private final Exception _error;
> > > +    private final int _code;
> > > +    /**
> > > +     * Construct a response to describe a error.
> > > +     *
> > > +     * @param request a request that produced this response. VCan be
> > null to denote that the request can not
> > > +     * be created.
> > > +     * @param ctx the processing context
> > > +     * @param ex the error
> > > +     * @param code HTTP error code
> > > +     * @param out the stream where the response is written
> > > +     *
> > > +     */
> > > +    public ErrorResponse(Request request, ServerContext ctx, Exception
> > ex, int code, OutputStream out)  {
> > > +        super(request, ctx, out);
> > > +        _error = ex;
> > > +        _code = code;
> > > +    }
> > > +
> > > +    /**
> > > +     * Writes the response.
> > > +     * The response is always a HTTP response with the error stack
> > trace.
> > > +     */
> > > +    public void writeOut() throws Exception {
> > > +        println("HTTP/1.1"); print(" " + _code); println("Error");
> > > +        printHeader("Connection",  "close");
> > > +        printHeader("Content-Type", "text/html", "charset=UTF-8");
> > > +        println();
> > > +        println("<html><body><pre>");
> > > +        _error.printStackTrace(this);
> > > +        println("Response from JEST");
> > > +
> > > +        println("</pre></body></html>");
> > > +        close();
> > > +    }
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ErrorResponse.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ErrorResponse.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/GETRequest.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/GETRequest.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/GETRequest.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/GETRequest.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,147 @@
> > > +/*
> > > + * 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.InputStream;
> > > +import java.io.OutputStream;
> > > +import java.net.HttpURLConnection;
> > > +import java.util.Iterator;
> > > +import java.util.List;
> > > +import java.util.Map;
> > > +
> > > +import javax.persistence.EntityManager;
> > > +import javax.persistence.EntityNotFoundException;
> > > +import javax.persistence.Query;
> > > +
> > > +import org.apache.openjpa.kernel.OpenJPAStateManager;
> > > +import org.apache.openjpa.kernel.StoreContext;
> > > +import org.apache.openjpa.meta.ClassMetaData;
> > > +import org.apache.openjpa.persistence.JPAFacadeHelper;
> > > +import org.apache.openjpa.util.ApplicationIds;
> > > +import org.apache.openjpa.util.ObjectNotFoundException;
> > > +
> > > +/**
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +@SuppressWarnings("serial")
> > > +public class GETRequest extends JESTRequest {
> > > +    public Response process(ServerContext server, OutputStream out)
> > throws Exception {
> > > +        String action = getAction();
> > > +        try {
> > > +            if ("find".equals(action)) {
> > > +                return find(server, out);
> > > +            } else {
> > > +                return resource(server, out);
> > > +            }
> > > +        } catch (Exception e) {
> > > +            return new ErrorResponse(this, server, new
> > RuntimeException("bad action " + action),
> > > +                HttpURLConnection.HTTP_BAD_REQUEST, out);
> > > +        }
> > > +    }
> > > +
> > > +    Response find(ServerContext server, OutputStream out)  throws
> > Exception {
> > > +        EntityManager em =
> > server.getPersistenceUnit().createEntityManager();
> > > +        Map<String, String> qualifiers = getQualifiers();
> > > +        Map<String, String> parameters = getParameters();
> > > +        if (parameters.size() < 2)
> > > +            throw new IllegalArgumentException("find must have at
> least
> > two parameters");
> > > +        Object[] pks = new Object[parameters.size()-1];
> > > +        Iterator<Map.Entry<String,String>> params =
> > parameters.entrySet().iterator();
> > > +        String alias = null;
> > > +        for (int i = 0; i < parameters.size(); i++) {
> > > +            if (i == 0) {
> > > +                alias = params.next().getKey();
> > > +            } else {
> > > +                pks[i-1] = params.next().getKey();
> > > +            }
> > > +        }
> > > +        ClassMetaData meta = server.resolve(alias);
> > > +        Object oid = ApplicationIds.fromPKValues(pks, meta);
> > > +        Object pc = em.find(meta.getDescribedType(), oid);
> > > +        if (pc != null) {
> > > +            OpenJPAStateManager sm =
> > ((StoreContext)JPAFacadeHelper.toBroker(em)).getStateManager(pc);
> > > +            return new JESTResponse(this, server, sm, out);
> > > +        } else {
> > > +            return new ErrorResponse(this, server, new
> > EntityNotFoundException("not found!"),
> > > +                HttpURLConnection.HTTP_NOT_FOUND, out);
> > > +        }
> > > +    }
> > > +
> > > +    Response query(ServerContext server, OutputStream out)  throws
> > Exception {
> > > +        EntityManager em =
> > server.getPersistenceUnit().createEntityManager();
> > > +        Map<String, String> qualifiers = getQualifiers();
> > > +        boolean named = isBooleanQualifier("named");
> > > +        boolean single = isBooleanQualifier("single");
> > > +        Map<String, String> parameters = getParameters();
> > > +        if (parameters.size() < 1)
> > > +            throw new IllegalArgumentException("find must have at
> least
> > one parameter");
> > > +        Iterator<Map.Entry<String,String>> params =
> > parameters.entrySet().iterator();
> > > +        Query query = null;
> > > +        int i = 0;
> > > +        for (Map.Entry<String, String> param : parameters.entrySet())
> {
> > > +            if (i == 0) {
> > > +                query = named ? em.createQuery(param.getKey()) :
> > em.createNamedQuery(param.getKey());
> > > +            } else {
> > > +                query.setParameter(param.getKey(), param.getValue());
> > > +            }
> > > +        }
> > > +        if (single) {
> > > +            Object result = query.getSingleResult();
> > > +            OpenJPAStateManager sm =
> > ((StoreContext)JPAFacadeHelper.toBroker(em)).getStateManager(result);
> > > +            return new JESTResponse(this, server, sm, out);
> > > +        } else {
> > > +            List<Object> result = query.getResultList();
> > > +            return new ErrorResponse(this, server, new
> > EntityNotFoundException("not found!"), 404, out);
> > > +        }
> > > +    }
> > > +
> > > +    Response resource(ServerContext server, OutputStream out)  throws
> > Exception {
> > > +        String resource = getAction();
> > > +        if (resource.length() == 0)
> > > +            resource = "index.html";
> > > +        String mimeType = getMimeType(resource);
> > > +//        InputStream in =
> >
> Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
> > > +        InputStream in = getClass().getResourceAsStream(resource);
> > > +        if (in == null) {
> > > +            return new ErrorResponse(this, server, new
> > ObjectNotFoundException(resource), 404, out);
> > > +        }
> > > +        if (server.getLog().isTraceEnabled())
> > > +            server.getLog().trace("Found resource " + resource);
> > > +        return mimeType.startsWith("image")
> > > +          ? new ImageResponse(this, server, in, mimeType, out)
> > > +          : new ResourceResponse(this, server, in, mimeType, out);
> > > +    }
> > > +
> > > +    boolean isBooleanQualifier(String key) {
> > > +        String q = getQualifier(key);
> > > +        return hasQualifier(key) && (q == null || "true".equals(q));
> > > +    }
> > > +
> > > +    String getMimeType(String resource) {
> > > +        int index = resource.lastIndexOf('.');
> > > +        String ext = (index != -1) ? resource.substring(index+1) : "";
> > > +        if (ext.equalsIgnoreCase("html") ||
> > ext.equalsIgnoreCase(".html")) return "text/html";
> > > +        if (ext.equalsIgnoreCase(".png") ||
> ext.equalsIgnoreCase(".ico")
> > || ext.equalsIgnoreCase("jpeg"))
> > > +            return "image/"+ext;
> > > +        return "text/html";
> > > +    }
> > > +
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/GETRequest.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/GETRequest.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ImageResponse.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ImageResponse.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ImageResponse.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ImageResponse.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,61 @@
> > > +/*
> > > + * 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.InputStream;
> > > +import java.io.OutputStream;
> > > +import java.io.RandomAccessFile;
> > > +
> > > +import javax.imageio.ImageIO;
> > > +
> > > +/**
> > > + * Sends an image as response.
> > > + *
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +@SuppressWarnings("serial")
> > > +public class ImageResponse extends AbstractResponse {
> > > +    private final InputStream _in;
> > > +    private final String _mimeType;
> > > +
> > > +    public ImageResponse(Request request, ServerContext ctx,
> InputStream
> > resource, String mimeType,
> > > +        OutputStream out) throws Exception {
> > > +        super(request, ctx, out);
> > > +        _in = resource;
> > > +        _mimeType = mimeType;
> > > +    }
> > > +
> > > +    public void writeOut() throws Exception {
> > > +        print(_request.getProtocol()); println("200 OK");
> > > +        printHeader("Connection",  "close");
> > > +        printHeader("Content-Type", _mimeType);
> > > +        println();
> > > +        byte[] b = new byte[1024];
> > > +        int i = 0;
> > > +        for (int l = 0; (l = _in.read(b)) != -1;) {
> > > +            write(b, 0, l);
> > > +            i += l;
> > > +        }
> > > +        printHeader("Content-Length", ""+i);
> > > +        _in.close();
> > > +        close();
> > > +    }
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ImageResponse.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ImageResponse.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTRequest.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTRequest.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTRequest.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTRequest.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,386 @@
> > > +/*
> > > + * 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.util.Arrays;
> > > +import java.util.Collections;
> > > +import java.util.HashMap;
> > > +import java.util.LinkedHashMap;
> > > +import java.util.LinkedList;
> > > +import java.util.List;
> > > +import java.util.Map;
> > > +import java.util.NoSuchElementException;
> > > +
> > > +/**
> > > + * A request carries requisite data for a JPA operation to be
> performed.
> > > + * The request is populated by parsing an input data stream.
> > > + *
> > > + *
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +@SuppressWarnings("serial")
> > > +public abstract class JESTRequest implements Request {
> > > +    private String _method;
> > > +    private String _protocol;
> > > +    private String _action;
> > > +    private String _body;
> > > +    private LinkedHashMap<String, String> _qualifiers = new
> > LinkedHashMap<String, String>();
> > > +    private LinkedHashMap<String, String> _params = new
> > LinkedHashMap<String, String>();
> > > +    private Map<String, List<String>> _headers = new HashMap<String,
> > List<String>>();
> > > +    private ParseState _state;
> > > +    private StringBuffer buf = new StringBuffer();
> > > +    private LinkedList<Token> _stack = new LinkedList<Token>();
> > > +
> > > +    public static final List<String> METHODS = Arrays.asList(new
> > String[]{"GET","POST","PUT","DELETE"});
> > > +
> > > +    /**
> > > +     * Parse States.
> > > +     */
> > > +    static enum ParseState {
> > > +        INIT, ACTION, QUALIFIER_KEY, QUALIFIER_VALUE, PARAM_KEY,
> > PARAM_VALUE, END
> > > +    };
> > > +
> > > +
> > > +    public String getMethod() {
> > > +        return _method;
> > > +    }
> > > +
> > > +    void setMethod(String method) {
> > > +        if (_method == null) {
> > > +            if (method != null &&
> > METHODS.contains(method.toUpperCase())) {
> > > +                _method = method.toUpperCase();
> > > +            } else {
> > > +                throw new IllegalArgumentException("Unsupported method
> "
> > + method);
> > > +            }
> > > +        } else if (!_method.equalsIgnoreCase(method)) {
> > > +            throw new IllegalStateException("Method can not be changed
> > to [" + method + "]. " +
> > > +                "Current method [" + _method + "]");
> > > +        }
> > > +    }
> > > +
> > > +    public String getProtocol() {
> > > +        return _protocol == null ? "HTTP/1.1" : _protocol;
> > > +    }
> > > +
> > > +    void setProtocol(String protocol) {
> > > +        if (_protocol == null) {
> > > +            if (protocol != null &&
> > protocol.toUpperCase().startsWith("HTTP")) {
> > > +                _protocol = protocol.toUpperCase();
> > > +            } else {
> > > +                throw new IllegalArgumentException("Unsupported
> protocol
> > " + protocol);
> > > +            }
> > > +        } else if (!_protocol.equalsIgnoreCase(protocol)) {
> > > +            throw new IllegalStateException("Protocol can not be
> changed
> > to [" + protocol + "]. " +
> > > +                "Current protocol [" + _protocol + "]");
> > > +        }
> > > +    }
> > > +
> > > +    /**
> > > +     * Sets an action. Once set, an action can not be modified.
> > > +     *
> > > +     * @param action
> > > +     */
> > > +    private void setAction(String action) {
> > > +        if (_action == null) {
> > > +            _action = action;
> > > +        } else if (!_action.equals(action)) {
> > > +            throw new IllegalStateException("Action can not be [" +
> > action + "]. Already set to [" + _action + "]");
> > > +        }
> > > +    }
> > > +
> > > +    public String getAction() {
> > > +        return _action == null ? "" : _action;
> > > +    }
> > > +
> > > +    public String getBody() {
> > > +        return _body;
> > > +    }
> > > +
> > > +    private void setQualifier(String key, String value) {
> > > +        _qualifiers.put(key, value);
> > > +    }
> > > +
> > > +    public String getQualifier(String key) {
> > > +        return _qualifiers.get(key);
> > > +    }
> > > +
> > > +    public Map<String, String> getQualifiers() {
> > > +        return Collections.unmodifiableMap(_qualifiers);
> > > +    }
> > > +
> > > +    public boolean hasQualifier(String key) {
> > > +        return _qualifiers.containsKey(key);
> > > +    }
> > > +
> > > +    private void setParameter(String key, String value) {
> > > +        _params.put(key, value);
> > > +    }
> > > +
> > > +    public String getParameter(String key) {
> > > +        return _params.get(key);
> > > +    }
> > > +
> > > +    public boolean hasParameter(String key) {
> > > +        return _params.containsKey(key);
> > > +    }
> > > +
> > > +    public Map<String, String> getParameters() {
> > > +        return Collections.unmodifiableMap(_params);
> > > +    }
> > > +
> > > +    public Map.Entry<String, String> getParameter(int n) {
> > > +        if (n >= _params.size())
> > > +            throw new NoSuchElementException("Index " + n + " size " +
> > _params.size());
> > > +        int i = 0;
> > > +        for (Map.Entry<String, String> entry : _params.entrySet()) {
> > > +            if (i == n) {
> > > +                return entry;
> > > +            }
> > > +            i++;
> > > +        }
> > > +        return null;
> > > +    }
> > > +
> > > +    public Map<String, List<String>> getHeaders() {
> > > +        return Collections.unmodifiableMap(_headers);
> > > +    }
> > > +
> > > +    public List<String> getHeader(String key) {
> > > +        return _headers.get(key);
> > > +    }
> > > +
> > > +
> > > +    public void read(List<String> lines) throws IOException {
> > > +        parse(lines.get(0));
> > > +        int i = 1;
> > > +        for (; i < lines.size(); i++) {
> > > +            String line = lines.get(i);
> > > +            if (line.length() == 0) {
> > > +                break;
> > > +            } else {
> > > +                parseHeader(line);
> > > +            }
> > > +        }
> > > +        parseBody(lines.subList(i, lines.size()));
> > > +    }
> > > +
> > > +    protected void parseHeader(String line) throws IOException {
> > > +        String key = null;
> > > +        StringBuilder token = new StringBuilder();
> > > +        int N = line.length();
> > > +        for (int i = 0; i < N; i++) {
> > > +            char c = line.charAt(i);
> > > +            if (c == ':' && key == null) {
> > > +                key = token.toString().trim();
> > > +                token.delete(0, token.length());
> > > +            } else {
> > > +                token.append(c);
> > > +            }
> > > +        }
> > > +        if (key != null) {
> > > +            _headers.put(key,
> > Collections.singletonList(token.toString().trim()));
> > > +        }
> > > +    }
> > > +
> > > +    protected void parseBody(List<String> lines) {
> > > +        if (lines == null || lines.isEmpty())
> > > +            return;
> > > +        for (String line : lines) {
> > > +            if (_body == null) {
> > > +                _body = line;
> > > +            } else {
> > > +                _body = _body + line;
> > > +            }
> > > +        }
> > > +    }
> > > +
> > > +    /**
> > > +     * Parses JEST stream and populates a request.
> > > +     *
> > > +     */
> > > +     protected void parse(String s) {
> > > +            char[] chars = s.toCharArray();
> > > +            _state = ParseState.INIT;
> > > +            _stack.clear();
> > > +
> > > +            for (int i = 0; i < chars.length; i++) {
> > > +                char ch = chars[i];
> > > +                switch (_state) {
> > > +                    case INIT:
> > > +                        if (ch == '/') {
> > > +                            transit(ParseState.ACTION);
> > > +                        } else if (!Character.isWhitespace(ch)) {
> > > +                            parseError(ch, i, s, true, ' ');
> > > +                        }
> > > +                        break;
> > > +
> > > +                    case ACTION:
> > > +                        if (ch == '/') {
> > > +                            transit(ParseState.QUALIFIER_KEY);
> > > +                        } else if (ch == '?') {
> > > +                            transit(ParseState.PARAM_KEY);
> > > +                        } else {
> > > +                            buf.append(ch);
> > > +                        }
> > > +                        break;
> > > +
> > > +                    case QUALIFIER_KEY:
> > > +                        if (Character.isJavaIdentifierPart(ch)) {
> > > +                            buf.append(ch);
> > > +                        } else if (ch == '=') {
> > > +                            transit(ParseState.QUALIFIER_VALUE);
> > > +                        } else if (ch == '/') {
> > > +                            transit(ParseState.QUALIFIER_KEY);
> > > +                        } else if (ch == '?') {
> > > +                            transit(ParseState.PARAM_KEY);
> > > +                        } else {
> > > +                            parseError(ch, i, s, true, '/', '?', '=');
> > > +                        }
> > > +                        break;
> > > +
> > > +                    case QUALIFIER_VALUE:
> > > +                        if (Character.isJavaIdentifierPart(ch)) {
> > > +                            buf.append(ch);
> > > +                        } else if (ch == '/') {
> > > +                            transit(ParseState.QUALIFIER_KEY);
> > > +                        } else if (ch == '?') {
> > > +                            transit(ParseState.PARAM_KEY);
> > > +                        } else {
> > > +                            parseError(ch, i, s, true, '/', '?');
> > > +                        }
> > > +                        break;
> > > +
> > > +                    case PARAM_KEY:
> > > +                        if (Character.isJavaIdentifierPart(ch)) {
> > > +                            buf.append(ch);
> > > +                        } else if (ch == '=') {
> > > +                            if (isQueryKey())
> > > +                                buf.append(ch);
> > > +                            else
> > > +                                transit(ParseState.PARAM_VALUE);
> > > +                        } else if (ch == ';') {
> > > +                            transit(ParseState.PARAM_KEY);
> > > +                        } else if (isQueryKey() && isQueryChar(ch)) {
> > > +                            buf.append(ch);
> > > +                        } else {
> > > +                            parseError(ch, i, s, true, ';', '=');
> > > +                        }
> > > +                        break;
> > > +
> > > +                    case PARAM_VALUE:
> > > +                        if (Character.isJavaIdentifierPart(ch)) {
> > > +                            buf.append(ch);
> > > +                        } else if (ch == ';') {
> > > +                            transit(ParseState.PARAM_KEY);
> > > +                        } else {
> > > +                            parseError(ch, i, s, true, ';');
> > > +                        }
> > > +                        break;
> > > +                    default:
> > > +                        throw new RuntimeException("ParseError: '" +
> ch
> > + "' at " + i + " in [" + s + "]. "
> > > +                            + "Unknown state " + _state);
> > > +                }
> > > +            }
> > > +            if (buf.length() > 0) {
> > > +                transit(ParseState.END);
> > > +            }
> > > +        }
> > > +
> > > +        /**
> > > +         * Affirms if parsing a query string.
> > > +         */
> > > +        private boolean isQueryKey() {
> > > +            return "query".equals(_action) && _stack.size() == 1;
> > > +        }
> > > +
> > > +        /**
> > > +         * Affirms if the given character is valid in a query string
> > > +         */
> > > +        private boolean isQueryChar(char c) {
> > > +            return c == ' ' || c == '.' || c == ':' || c == '?' || c
> ==
> > '\'';
> > > +        }
> > > +
> > > +        /**
> > > +         * Transitions to a new parse state.
> > > +         *
> > > +         * @param to target parse state
> > > +         */
> > > +        void transit(ParseState to) {
> > > +            String token = buf.toString();
> > > +            switch (_state) {
> > > +                case ACTION:
> > > +                    setAction(token);
> > > +                    break;
> > > +                case QUALIFIER_KEY:
> > > +                    setQualifier(token, null);
> > > +                    break;
> > > +                case QUALIFIER_VALUE:
> > > +                    setQualifier(_stack.peekLast().getValue(), token);
> > > +                    break;
> > > +                case PARAM_KEY:
> > > +                    setParameter(token, null);
> > > +                    break;
> > > +                case PARAM_VALUE:
> > > +                    setParameter(_stack.peekLast().getValue(), token);
> > > +                    break;
> > > +
> > > +            }
> > > +            if (_state != ParseState.INIT && to != ParseState.END) {
> > > +                _stack.add(new Token(_state, token));
> > > +            }
> > > +            buf.delete(0, buf.length());
> > > +            _state = to;
> > > +        }
> > > +
> > > +        protected void parseError(char ch, int pos, String line,
> boolean
> > java, char... expected) {
> > > +            throw new RuntimeException("ParseError: Encountered '" +
> ch
> > + "' at " + pos + " in [" + line + "] while "
> > > +                + "parsing " + _state + ". Expected " +
> > Arrays.toString(expected) + (java ? " or Java identifer" : ""));
> > > +
> > > +        }
> > > +
> > > +        /**
> > > +         * Token in a JEST stream.
> > > +         *
> > > +         */
> > > +        static class Token {
> > > +            final ParseState _type;
> > > +            final String _value;
> > > +
> > > +            public Token(ParseState type, String value) {
> > > +                _type = type;
> > > +                _value = value;
> > > +            }
> > > +
> > > +            public ParseState getType() {
> > > +                return _type;
> > > +            }
> > > +
> > > +            public String getValue() {
> > > +                return _value;
> > > +            }
> > > +
> > > +            public String toString() {
> > > +                return _value + "[" + _type + "]";
> > > +            }
> > > +        }
> > > +
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTRequest.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTRequest.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTResponse.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTResponse.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTResponse.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTResponse.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,71 @@
> > > +/*
> > > + * 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.io.PrintStream;
> > > +import java.io.PrintWriter;
> > > +import java.util.List;
> > > +import java.util.Map;
> > > +import java.util.Set;
> > > +
> > > +import org.apache.openjpa.kernel.OpenJPAStateManager;
> > > +import org.apache.openjpa.persistence.JPAFacadeHelper;
> > > +import org.w3c.dom.Document;
> > > +import org.w3c.dom.Element;
> > > +
> > > +/**
> > > + * Response of a JEST Request.
> > > + *
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +@SuppressWarnings("serial")
> > > +public class JESTResponse extends AbstractResponse {
> > > +    private final OpenJPAStateManager _sm;
> > > +
> > > +    public JESTResponse(Request request, ServerContext ctx,
> > OpenJPAStateManager sm, OutputStream out) throws Exception {
> > > +        super(request, ctx, out);
> > > +        _sm = sm;
> > > +    }
> > > +
> > > +    public String getContentType() {
> > > +        return "text/html";
> > > +    }
> > > +
> > > +    public void writeOut() throws Exception {
> > > +        print(_request.getProtocol()); println("200 OK");
> > > +        printHeader("Connection",  "close");
> > > +        printHeader("Content-Type", "text/html", "charset=UTF-8");
> > > +        println();
> > > +        println("<html><body><pre>");
> > > +        XMLEncoder encoder = new
> > XMLEncoder(_ctx.getPersistenceUnit().getMetamodel());
> > > +        Document doc = encoder.encode(_sm);
> > > +        encoder.writeDoc(doc, this);
> > > +        println("Response from JEST");
> > > +
> > > +        println("</pre></body></html>");
> > > +        close();
> > > +    }
> > > +
> > > +}
> > > +
> > > +
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTResponse.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JESTResponse.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONEncoder.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONEncoder.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONEncoder.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONEncoder.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,316 @@
> > > +/*
> > > + * 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.Reader;
> > > +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 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.persistence.meta.MetamodelImpl;
> > > +import org.w3c.dom.CDATASection;
> > > +import org.w3c.dom.Document;
> > > +import org.w3c.dom.Element;
> > > +
> > > +/**
> > > + * 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 JSONEncoder {
> > > +    /**
> > > +     * The element/attribute tags declared in
> > <code>jest-instance.xsd</code> XML schema.
> > > +     */
> > > +    public static final String ELEMENT_NULL_REF    = "null";
> > > +    public static final String ELEMENT_INSTANCE    = "instance";
> > > +    public static final String ELEMENT_REF         = "ref";
> > > +
> > > +
> > > +    private MetamodelHelper _model;
> > > +
> > > +    public JSONEncoder(MetamodelImpl model) {
> > > +        _model = new MetamodelHelper(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.
> > > +     */
> > > +    public StringBuilder encode(final OpenJPAStateManager sm) {
> > > +        return encode(sm, new HashSet<OpenJPAStateManager>(), 0,
> false);
> > > +    }
> > > +    StringBuilder indent(StringBuilder buf, int indent) {
> > > +        if (indent <= 0)
> > > +            return buf;
> > > +        char[] spaces = new char[indent*4];
> > > +        Arrays.fill(spaces, ' ');
> > > +        buf.insert(0, spaces);
> > > +        return buf;
> > > +    }
> > > +    StringBuilder end(StringBuilder buf, char ch, int indent) {
> > > +        char[] spaces = new char[indent*4];
> > > +        Arrays.fill(spaces, ' ');
> > > +        return buf.append("\r\n").append(spaces).append(ch);
> > > +    }
> > > +
> > > +    /**
> > > +     * 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 StringBuilder encode(final OpenJPAStateManager sm, final
> > Set<OpenJPAStateManager> visited,
> > > +        int indent, boolean indentPara) {
> > > +        if (visited == null) {
> > > +            throw new IllegalArgumentException("null closure for
> > encoder");
> > > +        }
> > > +        StringBuilder root =  indent(new StringBuilder("{"),
> indentPara
> > ? indent : 0);
> > > +        if (sm == null) {
> > > +            return root.append("null}");
> > > +        }
> > > +        boolean ref = !visited.add(sm);
> > > +        if (ref) {
> > > +            return indent(root.append(quoted("$ref")).append(":
> > ").append(ior(sm)).append('}'),
> > > +                indentPara ? indent : 0);
> > > +        } else {
> > > +            indent(root.append(quoted("$id")).append(":
> > ").append(ior(sm)), indentPara ? indent : 0);
> > > +        }
> > > +
> > > +        StringBuilder child = new StringBuilder();
> > > +        BitSet loaded = sm.getLoaded();
> > > +        StoreContext ctx = (StoreContext)sm.getGenericContext();
> > > +        List<Attribute<?, ?>> attrs =
> > _model.getAttributesInOrder(sm.getMetaData());
> > > +        for (int i = 0; i < attrs.size(); child = new StringBuilder(),
> > i++) {
> > > +            FieldMetaData fmd = ((Members.Member<?, ?>)
> > attrs.get(i)).fmd;
> > > +            if (!loaded.get(fmd.getIndex()))
> > > +                continue;
> > > +            Object value = sm.fetch(fmd.getIndex());
> > > +            child.append(quoted(fmd.getName())).append(": ");
> > > +            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.append(quoted(value));
> > > +                break;
> > > +
> > > +                case JavaTypes.PC:
> > > +                    if (value == null) {
> > > +                        child.append("null");
> > > +                    } else {
> > > +
>  child.append(encode(ctx.getStateManager(value),
> > visited, indent+1, false));
> > > +                    }
> > > +                    break;
> > > +
> > > +                case JavaTypes.ARRAY:
> > > +                    Object[] values = (Object[])value;
> > > +                    value = Arrays.asList(values);
> > > +                // no break;
> > > +                case JavaTypes.COLLECTION:
> > > +                    if (value == null) {
> > > +                        child.append("null");
> > > +                        break;
> > > +                    }
> > > +                    child.append("[");
> > > +                    Collection<?> members = (Collection<?>)value;
> > > +                    boolean basic = fmd.getElement().getTypeMetaData()
> > == null;
> > > +                    int k = 0;
> > > +                    for (Object o : members) {
> > > +                        child.append("\r\n");
> > > +                        if (o == null) {
> > > +                            child.append(indent(new
> > StringBuilder("null"), indent+1));
> > > +                        } else {
> > > +                            if (basic) {
> > > +                                child.append(indent(new
> > StringBuilder(quoted(o)), indent+1));
> > > +                            } else {
> > > +
> >  child.append(encode(ctx.getStateManager(o), visited, indent+1, true));
> > > +                            }
> > > +                        }
> > > +                    }
> > > +                    end(child, ']', indent+1);
> > > +                    break;
> > > +                case JavaTypes.MAP:
> > > +                    if (value == null) {
> > > +                        child.append("null");
> > > +                        break;
> > > +                    }
> > > +                    child.append("[");
> > > +                    Set<Map.Entry> entries = ((Map)value).entrySet();
> > > +                    boolean basicKey   =
> > fmd.getElement().getTypeMetaData() == null;
> > > +                    boolean basicValue =
> > fmd.getValue().getTypeMetaData() == null;
> > > +                    for (Map.Entry<?,?> e : entries) {
> > > +                        if (e.getKey() == null) {
> > > +                            child.append("null:");
> > > +                        } else {
> > > +                            if (basicKey) {
> > > +
> >  child.append(quoted(e.getKey())).append(":");
> > > +                            } else {
> > > +
> >  child.append(encode(ctx.getStateManager(e.getKey()), visited, indent+1,
> > true));
> > > +                            }
> > > +                        }
> > > +                        if (e.getValue() == null) {
> > > +                            child.append("null");
> > > +                        } else {
> > > +                            if (basicValue) {
> > > +                                child.append(quoted(e.getValue()));
> > > +                            } else {
> > > +
> >  child.append(encode(ctx.getStateManager(e.getValue()), visited,
> indent+1,
> > false));
> > > +                            }
> > > +                        }
> > > +                    }
> > > +                    break;
> > > +
> > > +                case JavaTypes.INPUT_STREAM:
> > > +                case JavaTypes.INPUT_READER:
> > > +                    child = new StringBuilder(fmd.getName());
> > > +                    if (value == null) {
> > > +                        child.append("null");
> > > +                    } else {
> > > +                        child.append(streamToString(value));
> > > +                    }
> > > +                    break;
> > > +
> > > +                case JavaTypes.PC_UNTYPED:
> > > +                case JavaTypes.OBJECT:
> > > +                case JavaTypes.OID:
> > > +                    System.err.println("Not handled " + fmd.getName()
> +
> > " of type " + fmd.getDeclaredType());
> > > +            }
> > > +
> > > +            if (child != null) {
> > > +                root.append("\r\n");
> > > +                root.append(indent(child, indent+1));
> > > +                if (loaded.length()-1 != i)
> > > +                    root.append(",");
> > > +           }
> > > +        }
> > > +        return end(root, '}', indent);
> > > +    }
> > > +
> > > +
> > > +    String ior(OpenJPAStateManager sm) {
> > > +        return quoted(typeOf(sm)+"-"+sm.getObjectId().toString());
> > > +    }
> > > +
> > > +    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();
> > > +    }
> > > +
> > > +
> > > +    /**
> > > +     * 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();
> > > +    }
> > > +
> > > +    String quoted(Object o) {
> > > +        if (o == null) return "null";
> > > +        if (o instanceof Number)
> > > +            return o.toString();
> > > +        return "\"" + o.toString() + "\"";
> > > +    }
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONEncoder.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/JSONEncoder.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,127 @@
> > > +/*
> > > + * 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.HashMap;
> > > +import java.util.List;
> > > +import java.util.Map;
> > > +
> > > +import javax.persistence.metamodel.Attribute;
> > > +import javax.persistence.metamodel.EntityType;
> > > +import javax.persistence.metamodel.ManagedType;
> > > +import javax.persistence.metamodel.Metamodel;
> > > +import javax.persistence.metamodel.SingularAttribute;
> > > +
> > > +import org.apache.openjpa.meta.ClassMetaData;
> > > +import org.apache.openjpa.meta.FieldMetaData;
> > > +import org.apache.openjpa.persistence.meta.MetamodelImpl;
> > > +
> > > +/**
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +public class MetamodelHelper {
> > > +    private MetamodelImpl _model;
> > > +    private Map<ManagedType<?>, List<Attribute<?, ?>>> _attrs = new
> > HashMap<ManagedType<?>, List<Attribute<?,?>>>();
> > > +
> > > +    public MetamodelHelper(MetamodelImpl model) {
> > > +        _model = model;
> > > +    }
> > > +
> > > +    public List<Attribute<?,?>> getAttributesInOrder(Class<?> cls) {
> > > +        return getAttributesInOrder(_model.managedType(cls));
> > > +    }
> > > +
> > > +    public List<Attribute<?,?>> getAttributesInOrder(ClassMetaData
> meta)
> > {
> > > +        return getAttributesInOrder(meta.getDescribedType());
> > > +    }
> > > +
> > > +    /**
> > > +     * Gets the attributes of the given type in defined order.
> > > +     * @param type
> > > +     * @return
> > > +     */
> > > +    public List<Attribute<?,?>> getAttributesInOrder(ManagedType<?>
> > type) {
> > > +        List<Attribute<?,?>> attrs = _attrs.get(type);
> > > +        if (attrs != null)
> > > +            return attrs;
> > > +        List<Attribute<?,?>> list = new
> > ArrayList<Attribute<?,?>>(type.getAttributes());
> > > +        Collections.sort(list, new AttributeComparator());
> > > +        _attrs.put(type, list);
> > > +        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 Integer getAttributeTypeCode(Attribute<?,?> attr) {
> > > +        if (isId(attr))
> > > +            return 0;
> > > +        if (isVersion(attr))
> > > +            return 1;
> > > +
> > > +      switch (attr.getPersistentAttributeType()) {
> > > +      case BASIC :
> > > +      case EMBEDDED:
> > > +          return 2;
> > > +      case ONE_TO_ONE:
> > > +      case MANY_TO_ONE:
> > > +          return 3;
> > > +      case ONE_TO_MANY:
> > > +      case MANY_TO_MANY:
> > > +      case ELEMENT_COLLECTION: return 4;
> > > +      default: return 5;
> > > +      }
> > > +    }
> > > +
> > > +    /**
> > > +     * Compares attribute by their qualification.
> > > +     * Identity
> > > +     * Version
> > > +     * Basic
> > > +     * Singular association
> > > +     * Plural association
> > > +     *
> > > +     */
> > > +    public static class AttributeComparator implements
> > Comparator<Attribute<?,?>> {
> > > +        @Override
> > > +        public int compare(Attribute<?, ?> a1, Attribute<?, ?> a2) {
> > > +            Integer t1 = getAttributeTypeCode(a1);
> > > +            Integer t2 = getAttributeTypeCode(a2);
> > > +            if (t1.equals(t2)) {
> > > +                return a1.getName().compareTo(a2.getName());
> > > +            } else {
> > > +                return t1.compareTo(t2);
> > > +            }
> > > +        }
> > > +    }
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/MetamodelHelper.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Request.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Request.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Request.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Request.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,138 @@
> > > +/*
> > > + * 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.io.Serializable;
> > > +import java.util.List;
> > > +import java.util.Map;
> > > +
> > > +/**
> > > + * A request from a remote client to a server to do something.
> > > + * The request arrives as stream of bytes from a remote location
> > > + * and if the server can interpret the protocol from the stream,
> > > + * then  make a concrete request object.
> > > + *
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +public interface Request extends Serializable {
> > > +    /**
> > > +     * Get the HTTP verb such as GET, POST
> > > +     *
> > > +     * @return uppercase string
> > > +     */
> > > +    String getMethod();
> > > +
> > > +    /**
> > > +     * Get the first path segment as intended persistence action such
> as
> > <code>find</code> or <code>query</code>
> > > +     *
> > > +     * @return lowercase action name. Can be empty.
> > > +     */
> > > +    String getAction();
> > > +
> > > +    /**
> > > +     * Get the protocol such as HTTP/1.1
> > > +     *
> > > +     * @return upper-case string
> > > +     */
> > > +    String getProtocol();
> > > +
> > > +    /**
> > > +     * Get the body, if any.
> > > +     *
> > > +     * @return body of the request. null if no body.
> > > +     */
> > > +    String getBody();
> > > +
> > > +    /**
> > > +     * Get the headers indexed by the keys.
> > > +     * Header values are list of Strings.
> > > +     *
> > > +     * @return empty map if there is no header
> > > +     */
> > > +    Map<String, List<String>> getHeaders();
> > > +
> > > +    /**
> > > +     * Get the header values for the given key.
> > > +     * @param key a key
> > > +     * @return null if no header value for the given key
> > > +     */
> > > +    List<String> getHeader(String key);
> > > +
> > > +    /**
> > > +     * Affirm if the the given qualifier is available in this request.
> > > +     *
> > > +     * @param key case-sensitive qualifier
> > > +     * @return true if the key is present.
> > > +     */
> > > +    boolean hasQualifier(String key);
> > > +
> > > +    /**
> > > +     * Gets the value for the given qualifier key.
> > > +     *
> > > +     * @param key case-sensitive qualifier
> > > +     * @return value of the qualifier. null if the key is absent.
> > > +     */
> > > +    String getQualifier(String key);
> > > +
> > > +    /**
> > > +     * Get all the qualifiers available in this request.
> > > +     *
> > > +     * @return key-value pairs of the qualifiers. Empty map if no
> > qualifier is present.
> > > +     */
> > > +    Map<String,String> getQualifiers();
> > > +
> > > +
> > > +    /**
> > > +     * Affirm if the the given parameter is available in this request.
> > > +     *
> > > +     * @param key case-sensitive parameter
> > > +     * @return true if the key is present.
> > > +     */
> > > +    boolean hasParameter(String key);
> > > +
> > > +
> > > +    /**
> > > +     * Gets the value for the given parameter key.
> > > +     *
> > > +     * @param key case-sensitive parameter
> > > +     * @return value of the parameter. null if the key is absent.
> > > +     */
> > > +    String getParameter(String key);
> > > +
> > > +    /**
> > > +     * Get all the parameters available in this request.
> > > +     *
> > > +     * @return key-value pairs of the parameters. Empty map if no
> > parameter is present.
> > > +     */
> > > +    Map<String,String> getParameters();
> > > +
> > > +    /**
> > > +     * Parse the request represented as a list of strings.
> > > +     *
> > > +     * @param lines each line of the request.
> > > +     * @throws IOException
> > > +     */
> > > +    void read(List<String> lines) throws IOException;
> > > +
> > > +    Response process(ServerContext server, OutputStream stream) throws
> > Exception;
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Request.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Request.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestFactory.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestFactory.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestFactory.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestFactory.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,63 @@
> > > +/*
> > > + * 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.HashMap;
> > > +import java.util.Map;
> > > +
> > > +/**
> > > + * A factory to create a specific type of request.
> > > + *
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +public class RequestFactory {
> > > +    private final String _protocol;
> > > +    private static Map<String, RequestFactory> _registered = new
> > HashMap<String, RequestFactory>();
> > > +    static {
> > > +        _registered.put("HTTP/1.0", new RequestFactory("HTTP/1.0"));
> > > +        _registered.put("HTTP/1.1", new RequestFactory("HTTP/1.1"));
> > > +    }
> > > +
> > > +    public static void register(String protocol, RequestFactory
> factory)
> > {
> > > +        _registered.put(protocol, factory);
> > > +    }
> > > +
> > > +    private RequestFactory(String proto) {
> > > +        _protocol = proto;
> > > +    }
> > > +
> > > +    public static RequestFactory getFactory(String protocol) {
> > > +        return _registered.get(protocol);
> > > +    }
> > > +
> > > +    Request createRequest(String method) {
> > > +        JESTRequest request = null;
> > > +        if ("GET".equalsIgnoreCase(method)) {
> > > +            request = new GETRequest();
> > > +        } else {
> > > +            throw new UnsupportedOperationException();
> > > +        }
> > > +        request.setProtocol(_protocol);
> > > +        request.setMethod(method.toUpperCase());
> > > +        return request;
> > > +
> > > +    }
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestFactory.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestFactory.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestHandler.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestHandler.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestHandler.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestHandler.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,147 @@
> > > +/*
> > > + * 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.IOException;
> > > +import java.io.InputStream;
> > > +import java.io.InputStreamReader;
> > > +import java.io.OutputStream;
> > > +import java.net.HttpURLConnection;
> > > +import java.net.Socket;
> > > +import java.net.SocketException;
> > > +import java.util.ArrayList;
> > > +import java.util.Collections;
> > > +import java.util.Iterator;
> > > +import java.util.List;
> > > +import java.util.Map;
> > > +import java.util.Set;
> > > +import java.util.concurrent.Callable;
> > > +
> > > +import javax.persistence.EntityManager;
> > > +import javax.persistence.EntityNotFoundException;
> > > +
> > > +import org.apache.openjpa.kernel.OpenJPAStateManager;
> > > +import org.apache.openjpa.kernel.StoreContext;
> > > +import org.apache.openjpa.lib.log.Log;
> > > +import org.apache.openjpa.lib.util.Localizer;
> > > +import org.apache.openjpa.meta.ClassMetaData;
> > > +import org.apache.openjpa.meta.FieldMetaData;
> > > +import org.apache.openjpa.persistence.JPAFacadeHelper;
> > > +import org.apache.openjpa.persistence.OpenJPAPersistence;
> > > +import org.apache.openjpa.util.ApplicationIds;
> > > +
> > > +/**
> > > + * Handles a request from a remote client.
> > > + * Reads the socket data.
> > > + * Populates the request.
> > > + * Determines the processor based on request method and action.
> > > + * Delegates to the processor.
> > > + * Processor generates the response.
> > > + * Writes the response to the stream.
> > > + *
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +public class RequestHandler implements Callable<Void> {
> > > +    private static final int SPACE = ' ';
> > > +    private final Socket _socket;
> > > +    private final ServerContext _server;
> > > +    private final Log _log;
> > > +    private static final Localizer _loc =
> > Localizer.forPackage(RequestHandler.class);
> > > +
> > > +    public RequestHandler(Socket socket, ServerContext server) {
> > > +        _socket = socket;
> > > +        _server = server;
> > > +        _log = _server.getLog();
> > > +    }
> > > +
> > > +    public Void call() throws Exception {
> > > +        Request request = null;
> > > +        Response response = null;
> > > +        try {
> > > +            request = readRequest(_socket.getInputStream());
> > > +            response = request.process(_server,
> > _socket.getOutputStream());
> > > +        } catch (Exception e) {
> > > +            response = new ErrorResponse(request, _server, e,
> > HttpURLConnection.HTTP_INTERNAL_ERROR,
> > > +                _socket.getOutputStream());
> > > +        }
> > > +        response.writeOut();
> > > +        return null;
> > > +    }
> > > +
> > > +
> > > +
> > > +    /**
> > > +     * Reads the given CR-LF delimited stream.
> > > +     * The first line is scanned for the method (first space-delimited
> > String) and protocol (the last
> > > +     * space-delimited String). Accordingly a request is created and
> > rest of the input stream content
> > > +     * is parsed by the request itself.
> > > +     *
> > > +     * @param input
> > > +     * @throws IOException
> > > +     */
> > > +    public Request readRequest(InputStream input) throws IOException {
> > > +        if (_log.isTraceEnabled())
> > > +            _log.trace("Reading request from the input stream ");
> > > +
> > > +        BufferedReader reader = new BufferedReader(new
> > InputStreamReader(input));
> > > +        String status = reader.readLine();
> > > +        if (_log.isInfoEnabled())
> > > +            _log.info("Status Line [" + status + "]");
> > > +        int spaceFirst = status.indexOf(SPACE);
> > > +        if (spaceFirst == -1)
> > > +            throw new IOException("HTTP Method could not be determined
> > from [" + status + "]");
> > > +        int spaceLast = status.lastIndexOf(SPACE);
> > > +        if (spaceLast == -1)
> > > +            throw new IOException("HTTP Protocol could not be
> determined
> > from [" + status + "]");
> > > +        String method = status.substring(0, spaceFirst);
> > > +        String protocol = status.substring(spaceLast+1);
> > > +        String path = status.substring(spaceFirst+1, spaceLast);
> > > +        Request request =
> > RequestFactory.getFactory(protocol).createRequest(method);
> > > +        List<String> lines = new ArrayList<String>();
> > > +        if (path.equals("/")) {
> > > +            lines.add(path);
> > > +        } else {
> > > +            lines = readlines(reader);
> > > +            lines.add(0, path);
> > > +        }
> > > +        if (lines.isEmpty()) {
> > > +            throw new IOException("No CR-LF delimited lines could be
> > read from " + input);
> > > +        }
> > > +        request.read(lines);
> > > +        return request;
> > > +    }
> > > +
> > > +
> > > +    List<String> readlines(BufferedReader reader) throws IOException {
> > > +        List<String> buffers = new ArrayList<String>();
> > > +        String line;
> > > +        while ((line = reader.readLine()) != null && line.length() >
> 0)
> > {
> > > +            buffers.add(line);
> > > +        }
> > > +        return buffers;
> > > +    }
> > > +
> > > +
> > > +    public String toString() {
> > > +        return _socket.getInetAddress()+":"+_socket.getPort();
> > > +    }
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestHandler.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/RequestHandler.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ResourceResponse.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ResourceResponse.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ResourceResponse.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ResourceResponse.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,54 @@
> > > +/*
> > > + * 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.InputStream;
> > > +import java.io.OutputStream;
> > > +import java.io.RandomAccessFile;
> > > +
> > > +import javax.imageio.ImageIO;
> > > +
> > > +/**
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +@SuppressWarnings("serial")
> > > +public class ResourceResponse extends AbstractResponse {
> > > +    private final InputStream _in;
> > > +    private final String _mimeType;
> > > +    public ResourceResponse(Request request, ServerContext ctx,
> > InputStream resource, String mimeType,
> > > +        OutputStream out) throws Exception {
> > > +        super(request, ctx, out);
> > > +        _in = resource;
> > > +        _mimeType = mimeType;
> > > +    }
> > > +
> > > +    public void writeOut() throws Exception {
> > > +        print(_request.getProtocol()); println("200 OK");
> > > +        printHeader("Connection",  "close");
> > > +        printHeader("Content-Type", _mimeType, "charset=UTF-8");
> > > +        println();
> > > +        for (int c = 0; (c = _in.read()) != -1;) {
> > > +           print((char)c);
> > > +        }
> > > +        _in.close();
> > > +        close();
> > > +    }
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ResourceResponse.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/ResourceResponse.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Response.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Response.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Response.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Response.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,31 @@
> > > +/*
> > > + * 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.Serializable;
> > > +
> > > +/**
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +public interface Response extends Serializable {
> > > +//    void setHeader(String key, String value);
> > > +    void writeOut() throws Exception;
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Response.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Response.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > > Added:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Server.java
> > > URL:
> >
> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Server.java?rev=1028093&view=auto
> > >
> >
> ==============================================================================
> > > ---
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Server.java
> > (added)
> > > +++
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Server.java
> > Wed Oct 27 20:42:44 2010
> > > @@ -0,0 +1,230 @@
> > > +/*
> > > + * 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.net.ServerSocket;
> > > +import java.net.Socket;
> > > +import java.util.concurrent.ExecutorService;
> > > +import java.util.concurrent.Executors;
> > > +
> > > +import javax.persistence.EntityManagerFactory;
> > > +
> > > +import org.apache.openjpa.conf.OpenJPAConfiguration;
> > > +import org.apache.openjpa.lib.conf.Configurable;
> > > +import org.apache.openjpa.lib.conf.Configuration;
> > > +import org.apache.openjpa.lib.log.Log;
> > > +import org.apache.openjpa.lib.util.Localizer;
> > > +import org.apache.openjpa.meta.ClassMetaData;
> > > +import org.apache.openjpa.meta.MetaDataRepository;
> > > +import org.apache.openjpa.persistence.EntityManagerFactoryImpl;
> > > +
> > > +
> > > +/**
> > > + * A server running on an independent thread that allows a remote,
> > language-neutral client to access OpenJPA runtime.
> > > + *
> > > + * @author Pinaki Poddar
> > > + *
> > > + */
> > > +public class Server implements ServerContext, Configurable, Runnable {
> > > +    private ServerSocket _listenSocket;
> > > +    protected ExecutorService _executors;
> > > +    public final static int DEFAULT_PORT = 6789;
> > > +    protected int _port = DEFAULT_PORT;
> > > +    protected int _range = 1;
> > > +    protected String _format = "xml";
> > > +    protected Log _log;
> > > +    protected Thread _thread;
> > > +    private EntityManagerFactoryImpl _ctx;
> > > +    private static Localizer _loc =
> Localizer.forPackage(Server.class);
> > > +
> > > +    /**
> > > +     * Sets the persistence unit context in which this server will
> serve
> > requests.
> > > +     * The context must be set before operation.
> > > +     *
> > > +     * @param emf an implementation of OpenJPA Persistence Unit. Must
> > not be null.
> > > +     */
> > > +    public void setContext(EntityManagerFactoryImpl emf) {
> > > +        if (emf == null)
> > > +            throw new NullPointerException();
> > > +        _ctx = emf;
> > > +    }
> > > +
> > > +    /**
> > > +     * Gets the persistence unit context in which this server serves
> > requests.
> > > +     *
> > > +     * @param emf an implementation of OpenJPA Persistence Unit.
> > > +     */
> > > +    public EntityManagerFactoryImpl getPersistenceUnit() {
> > > +        return _ctx;
> > > +    }
> > > +
> > > +    public Log getLog() {
> > > +        return _log;
> > > +    }
> > > +
> > > +    /**
> > > +     * Start the server in a daemon thread.
> > > +     * This method is idempotent.
> > > +     *
> > > +     * @return true if the server has started by this call or already
> > running.
> > > +     */
> > > +    public synchronized boolean start() {
> > > +        try {
> > > +            if (_thread != null)
> > > +                return true;
> > > +            if (createServerSocket()) {
> > > +                _thread = new Thread(this);
> > > +                _thread.setDaemon(true);
> > > +                _thread.start();
> > > +                return true;
> > > +            }
> > > +            return false;
> > > +        } catch (Exception ex) {
> > > +            ex.printStackTrace();
> > > +            return false;
> > > +        }
> > > +    }
> > > +
> > > +    /**
> > > +     * Stops the server.
> > > +     */
> > > +    public synchronized void stop() {
> > > +        _thread.interrupt();
> > > +        _thread = null;
> > > +        _executors.shutdownNow();
> > > +    }
> > > +
> > > +    /**
> > > +     * Sets the port in which the server will listen.
> > > +     *
> > > +     * @param port a positive integer.
> > > +     */
> > > +    public void setPort(int port) {
> > > +        _port = port;
> > > +    }
> > > +
> > > +    /**
> > > +     * Gets the current port.
> > > +     *
> > > +     * @return the port number. Defaults to default HTTP port.
> > > +     */
> > > +    public int getPort() {
> > > +        return _port;
> > > +    }
> > > +
> > > +    /**
> > > +     * Sets the range of ports the server will attempt at start.
> > > +     *
> > > +     * @param range a positive integer.
> > > +     */
> > > +    public void setRange(int range) {
> > > +        if (range > 0)
> > > +            _range = range;
> > > +    }
> > > +
> > > +    public void setFormat(String format) {
> > > +        _format = format;
> > > +    }
> > > +
> > > +    public String getFormat() {
> > > +        return _format;
> > > +    }
> > > +
> > > +    /**
> > > +     * Sets the range of ports the server will attempt at start.
> > > +     * @return  a positive integer. Defaults to 1.
> > > +     */
> > > +    public int getRange() {
> > > +        return _range;
> > > +    }
> > > +
> > > +    public void run() {
> > > +        _log.info(_loc.get("server-starting", this));
> > > +
> > > +        _executors = Executors.newCachedThreadPool();
> > > +        while (!Thread.interrupted()) {
> > > +            try {
> > > +                Socket socket = _listenSocket.accept();
> > > +                if (_log.isTraceEnabled())
> > > +                    _log.trace(_loc.get("server-request", socket));
> > > +                RequestHandler request = new RequestHandler(socket,
> > this);
> > > +                _executors.submit(request);
> > > +            } catch (IOException e) {
> > > +                e.printStackTrace();
> > > +            }
> > > +        }
> > > +    }
> > > +
> > > +    private boolean createServerSocket() {
> > > +        int p = _port;
> > > +        int p2 = p + _range;
> > > +        Exception error = null;
> > > +        for (; _listenSocket == null && p < p2; ) {
> > > +            try {
> > > +                _listenSocket = new ServerSocket(p);
> > > +            } catch (IOException ex) {
> > > +                p++;
> > > +                error = ex;
> > > +            }
> > > +        }
> > > +        if (_listenSocket != null) {
> > > +            if (p != _port) {
> > > +                _port = p;
> > > +                _log.warn(_loc.get("server-reconfigured", _port));
> > > +            }
> > > +        } else {
> > > +            if (error != null) {
> > > +                _log.warn(_loc.get("server-failed", this, _port,
> > error));
> > > +            }
> > > +        }
> > > +        return _listenSocket != null;
> > > +    }
> > > +
> > > +    // Configurable contract
> > > +    public void setConfiguration(Configuration conf) {
> > > +        _log = conf.getLog("Remote");
> > > +    }
> > > +
> > > +    public void startConfiguration() {
> > > +    }
> > > +
> > > +    public void endConfiguration() {
> > > +    }
> > > +
> > > +
> > > +    // Server side utilities
> > > +
> > > +    /**
> > > +     * Resolves the given alias to a persistent class meta data.
> > > +     *
> > > +     * @exception if no meta data available for the given alias
> > > +     */
> > > +    public ClassMetaData resolve(String alias) {
> > > +        MetaDataRepository repos =
> > _ctx.getConfiguration().getMetaDataRepositoryInstance();
> > > +        return repos.getMetaData(alias,
> > Thread.currentThread().getContextClassLoader(), true);
> > > +    }
> > > +
> > > +    public String toString() {
> > > +        if (_listenSocket == null) return "JEST Server [not strated]";
> > > +        return "JEST Server " +
> > _listenSocket.getInetAddress()+":"+_listenSocket.getLocalPort();
> > > +    }
> > > +
> > > +}
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Server.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:eol-style = native
> > >
> > > Propchange:
> >
> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/jest/Server.java
> > >
> >
> ------------------------------------------------------------------------------
> > >     svn:mime-type = text/plain
> > >
> > >
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message