You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fg...@apache.org on 2009/06/05 11:05:22 UTC

svn commit: r781949 [3/5] - in /incubator/chemistry/trunk/chemistry: ./ chemistry-atompub-client/ chemistry-atompub-client/src/ chemistry-atompub-client/src/main/ chemistry-atompub-client/src/main/java/ chemistry-atompub-client/src/main/java/org/ chemi...

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/APPType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/APPType.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeEntryReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeEntryReader.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeEntryReader.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeEntryReader.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,89 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.app.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.chemistry.PropertyDefinition;
+import org.apache.chemistry.atompub.CMIS;
+import org.apache.chemistry.atompub.client.common.atom.AbstractEntryReader;
+import org.apache.chemistry.atompub.client.common.atom.ReadContext;
+import org.apache.chemistry.atompub.client.common.xml.ChildrenNavigator;
+import org.apache.chemistry.atompub.client.common.xml.StaxReader;
+
+/**
+ *
+ */
+public class TypeEntryReader extends AbstractEntryReader<APPType> {
+
+    public final static TypeEntryReader INSTANCE = new TypeEntryReader();
+
+    @Override
+    protected APPType createObject(ReadContext ctx) {
+        APPType type = new APPType((APPConnection) ctx.getConnection());
+        return type;
+    }
+
+    @Override
+    protected void readAtomElement(ReadContext ctx, StaxReader reader,
+            APPType object) throws XMLStreamException {
+        // read only links - optimization to avoid useless operations
+        if ("link".equals(reader.getLocalName())) {
+            String rel = reader.getAttributeValue(ATOM_NS, "rel");
+            String href = reader.getAttributeValue(ATOM_NS, "href");
+            object.addLink(rel, href);
+        }
+    }
+
+    @Override
+    protected void readCmisElement(ReadContext context, StaxReader reader,
+            APPType entry) throws XMLStreamException {
+        if (CMIS.DOCUMENT_TYPE.getLocalPart().equals(reader.getLocalName())) {
+            ChildrenNavigator children = reader.getChildren();
+            Map<String, String> map = new HashMap<String, String>();
+            Map<String, PropertyDefinition> pdefs = null;
+            while (children.next()) {
+                if (reader.getLocalName().startsWith("property")) {
+                    if (pdefs == null) {
+                        pdefs = new HashMap<String, PropertyDefinition>();
+                    }
+                    PropertyDefinition pdef = readPropertyDef(reader);
+                    if (pdef.getName() == null) {
+                        throw new IllegalArgumentException(
+                                "Invalid property definition: no name given");
+                    }
+                    pdefs.put(pdef.getName(), pdef);
+                } else {
+                    try {
+                        map.put(reader.getLocalName(), reader.getElementText());
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+            entry.init(map, pdefs);
+        }
+    }
+
+    protected PropertyDefinition readPropertyDef(StaxReader reader)
+            throws XMLStreamException {
+        return APPPropertyDefinition.fromXml(reader);
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeEntryReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeEntryReader.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeFeedReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeFeedReader.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeFeedReader.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeFeedReader.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,52 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.app.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.chemistry.Type;
+import org.apache.chemistry.atompub.client.common.atom.AbstractFeedReader;
+import org.apache.chemistry.atompub.client.common.xml.StaxReader;
+
+/**
+ *
+ */
+public class TypeFeedReader extends
+        AbstractFeedReader<Map<String, Type>, APPType> {
+
+    public final static TypeFeedReader INSTANCE = new TypeFeedReader();
+
+    public TypeFeedReader() {
+        super(TypeEntryReader.INSTANCE);
+    }
+
+    public TypeFeedReader(TypeEntryReader entryReader) {
+        super(entryReader);
+    }
+
+    @Override
+    protected void addEntry(Map<String, Type> feed, APPType entry) {
+        feed.put(entry.getId(), entry);
+    }
+
+    @Override
+    protected Map<String, Type> createFeed(StaxReader reader) {
+        return new HashMap<String, Type>();
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeFeedReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/model/TypeFeedReader.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ExtensionService.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ExtensionService.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ExtensionService.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ExtensionService.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,52 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.app.service;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * An extension service implementation must have a constructor that takes one
+ * argument of type {@link ServiceContext} used by the service to initialize
+ * itself.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExtensionService {
+
+    /**
+     * Whether or not the service is a singleton (relative to its scope). For
+     * connection bound services the singleton will live in the scope of the
+     * connection. This means a new different will be used for each connection.
+     * If not bound to a connection a singleton service will live as long the
+     * repository which is bound id used.. Non singleton services will be
+     * instantiated at each lookup.
+     *
+     * @return true if singleton, false otherwise.
+     */
+    boolean singleton() default true;
+
+    /**
+     * Whether or not this service require to be bound on a connection
+     *
+     * @return true if the service requires a connection, false otherwise
+     */
+    boolean requiresConnection() default false;
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ExtensionService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ExtensionService.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceContext.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceContext.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceContext.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceContext.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,55 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.app.service;
+
+import org.apache.chemistry.Connection;
+import org.apache.chemistry.Repository;
+
+/**
+ *
+ */
+public class ServiceContext {
+
+    protected ServiceInfo info;
+
+    protected Repository repository;
+
+    protected Connection connection;
+
+    public ServiceContext(ServiceInfo info, Repository repository) {
+        this.info = info;
+        this.repository = repository;
+    }
+
+    public ServiceContext(ServiceInfo info, Connection connection) {
+        this(info, connection.getRepository());
+        this.connection = connection;
+    }
+
+    public ServiceInfo getInfo() {
+        return info;
+    }
+
+    public Connection getConnection() {
+        return connection;
+    }
+
+    public Repository getRepository() {
+        return repository;
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceContext.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceEntryReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceEntryReader.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceEntryReader.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceEntryReader.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,60 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.app.service;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.chemistry.atompub.client.common.atom.AbstractEntryReader;
+import org.apache.chemistry.atompub.client.common.atom.ReadContext;
+import org.apache.chemistry.atompub.client.common.xml.ParseException;
+import org.apache.chemistry.atompub.client.common.xml.StaxReader;
+
+/**
+ *
+ */
+public class ServiceEntryReader extends AbstractEntryReader<ServiceInfo> {
+
+    @Override
+    protected ServiceInfo createObject(ReadContext ctx) {
+        return new ServiceInfo();
+    }
+
+    @Override
+    protected void readAtomElement(ReadContext ctx, StaxReader reader,
+            ServiceInfo object) throws XMLStreamException {
+        String name = reader.getLocalName();
+        if ("id".equals(name)) {
+            String id = reader.getElementText();
+            int p = id.lastIndexOf(':');
+            if (p == -1) {
+                throw new ParseException("Invalid service id. " + id);
+            }
+            id = id.substring(p + 1);
+            object.setId(id);
+        } else if ("link".equals(name)) {
+            String rel = reader.getAttributeValue("rel");
+            if ("edit".equals(rel)) {
+                object.setHref(rel);
+            }
+        } else if ("title".equals(name)) {
+            object.setTitle(reader.getElementText());
+        } else if ("content".equals(name)) {
+            object.setSummary(reader.getElementText());
+        }
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceEntryReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceEntryReader.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceFeedReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceFeedReader.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceFeedReader.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceFeedReader.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,51 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.app.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.chemistry.atompub.client.common.atom.AbstractFeedReader;
+import org.apache.chemistry.atompub.client.common.xml.StaxReader;
+
+/**
+ *
+ */
+public class ServiceFeedReader extends
+        AbstractFeedReader<Map<String, ServiceInfo>, ServiceInfo> {
+
+    private final static ServiceFeedReader builder = new ServiceFeedReader();
+
+    public static ServiceFeedReader getBuilder() {
+        return builder;
+    }
+
+    public ServiceFeedReader() {
+        super(new ServiceEntryReader());
+    }
+
+    @Override
+    protected void addEntry(Map<String, ServiceInfo> feed, ServiceInfo entry) {
+        feed.put(entry.id, entry);
+    }
+
+    @Override
+    protected Map<String, ServiceInfo> createFeed(StaxReader reader) {
+        return new HashMap<String, ServiceInfo>();
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceFeedReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceFeedReader.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceInfo.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceInfo.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceInfo.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceInfo.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,134 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.app.service;
+
+import java.lang.reflect.Constructor;
+
+import org.apache.chemistry.atompub.client.app.APPContentManager;
+
+/**
+ *
+ */
+public class ServiceInfo {
+
+    public String id;
+
+    public String title;
+
+    public String summary;
+
+    public String href;
+
+    protected Class<?> itf;
+
+    protected Constructor<?> ctor;
+
+    protected boolean isSingleton;
+
+    protected boolean requiresConnection;
+
+    public ServiceInfo() {
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public void setSummary(String summary) {
+        this.summary = summary;
+    }
+
+    public void setHref(String href) {
+        this.href = href;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public String getSummary() {
+        return summary;
+    }
+
+    public String getHref() {
+        return href;
+    }
+
+    public boolean isSingleton() {
+        getServiceCtor();
+        return isSingleton;
+    }
+
+    public boolean requiresConnection() {
+        getServiceCtor();
+        return requiresConnection;
+    }
+
+    public Constructor<?> getServiceCtor() {
+        if (ctor == null) {
+            try {
+                Class<?> itf = Class.forName(id);
+                Class<?> clazz = APPContentManager.getServiceClass(itf);
+                if (clazz == null) { // no service registered for the given
+                                     // interface
+                    return null;
+                }
+                ExtensionService anno = clazz.getAnnotation(ExtensionService.class);
+                if (anno == null) {
+                    throw new IllegalStateException("Class " + clazz
+                            + " is not an extension service!");
+                }
+                requiresConnection = anno.requiresConnection();
+                isSingleton = anno.singleton();
+                ctor = clazz.getConstructor(new Class<?>[] { ServiceContext.class });
+            } catch (Exception e) {
+                e.printStackTrace(); // TODO handle errors
+            }
+        }
+        return ctor;
+    }
+
+    public Class<?> getServiceClass() {
+        Constructor<?> ctor = getServiceCtor();
+        return ctor == null ? null : ctor.getDeclaringClass();
+    }
+
+    public Class<?> getInterfaceClass() {
+        return itf;
+    }
+
+    public Object newInstance(ServiceContext ctx) {
+        Constructor<?> ctor = getServiceCtor();
+        if (ctor == null) {
+            return null;
+        }
+        try {
+            return ctor.newInstance(new Object[] { ctx });
+        } catch (Exception e) {
+            e.printStackTrace();// TODO handle errors
+            return null;
+        }
+    }
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/app/service/ServiceInfo.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterFactory.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterFactory.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterFactory.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterFactory.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,28 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.common;
+
+/**
+ *
+ */
+public interface AdapterFactory {
+
+    Class<?>[] getAdapterTypes();
+
+    <T> T getAdapter(Object obj, Class<T> adapterType);
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterFactory.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterManager.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterManager.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterManager.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterManager.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,78 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.common;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+@SuppressWarnings("unchecked")
+public class AdapterManager implements ClassRegistry {
+
+    // adaptableClass => { adapterClass => adapterFactory }
+    protected Map<Class<?>, Map<Class<?>, AdapterFactory>> registry;
+
+    public AdapterManager() {
+        this.registry = new HashMap<Class<?>, Map<Class<?>, AdapterFactory>>();
+    }
+
+    public synchronized void registerAdapters(Class<?> clazz,
+            AdapterFactory factory) {
+        Map<Class<?>, AdapterFactory> adapters = registry.get(clazz);
+        if (adapters == null) {
+            adapters = new HashMap<Class<?>, AdapterFactory>();
+        }
+        for (Class<?> adapterType : factory.getAdapterTypes()) {
+            adapters.put(adapterType, factory);
+        }
+        registry.put(clazz, adapters);
+    }
+
+    public void unregisterAdapters(Class<?> clazz) {
+        // TODO implement
+    }
+
+    public void unregisterAdapterFactory(Class<?> factory) {
+        // TODO implement
+    }
+
+    public synchronized AdapterFactory getAdapterFactory(Class<?> adaptee,
+            Class<?> adapter) {
+        Map<Class<?>, AdapterFactory> adapters = (Map<Class<?>, AdapterFactory>) ClassLookup.lookup(
+                adaptee, this);
+        if (adapters != null) {
+            return adapters.get(adapter);
+        }
+        return null;
+    }
+
+    public <T> T getAdapter(Object adaptee, Class<T> adapter) {
+        AdapterFactory factory = getAdapterFactory(adaptee.getClass(), adapter);
+        return factory == null ? null : factory.getAdapter(adaptee, adapter);
+    }
+
+    public Object get(Class<?> clazz) {
+        return registry.get(clazz);
+    }
+
+    public void put(Class<?> clazz, Object value) {
+        registry.put(clazz, (Map<Class<?>, AdapterFactory>) value);
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/AdapterManager.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassLookup.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassLookup.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassLookup.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassLookup.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,102 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.common;
+
+/**
+ * A Class keyed map sensible to class hierarchy. This map provides an
+ * additional method {@link #lookup(Class)} that can be used to lookup
+ * compatible to the given one depending on the class hierarchy.
+ */
+public class ClassLookup {
+
+    private static final long serialVersionUID = 1L;
+
+    public static Object lookup(Class<?> key, ClassRegistry registry) {
+        Object v = registry.get(key);
+        if (v == null) {
+            Class<?> sk = key.getSuperclass();
+            if (sk != null) {
+                v = registry.get(sk);
+            }
+            Class<?>[] itfs = null;
+            if (v == null) { // try interfaces
+                itfs = key.getInterfaces();
+                for (Class<?> itf : itfs) {
+                    v = registry.get(itf);
+                    if (v != null) {
+                        break;
+                    }
+                }
+            }
+            if (v == null) {
+                if (sk != null) { // superclass
+                    v = lookup(sk, registry);
+                }
+                if (v == null) { // interfaces
+                    for (Class<?> itf : itfs) {
+                        v = lookup(itf, registry);
+                        if (v != null) {
+                            break;
+                        }
+                    }
+                }
+            }
+            if (v != null) {
+                registry.put(key, v);
+            }
+        }
+        return v;
+    }
+
+    public static Object lookup(Class<?> key, ClassNameRegistry registry) {
+        Object v = registry.get(key.getName());
+        if (v == null) {
+            Class<?> sk = key.getSuperclass();
+            if (sk != null) {
+                v = registry.get(sk.getName());
+            }
+            Class<?>[] itfs = null;
+            if (v == null) { // try interfaces
+                itfs = key.getInterfaces();
+                for (Class<?> itf : itfs) {
+                    v = registry.get(itf.getName());
+                    if (v != null) {
+                        break;
+                    }
+                }
+            }
+            if (v == null) {
+                if (sk != null) { // superclass
+                    v = lookup(sk, registry);
+                }
+                if (v == null) { // interfaces
+                    for (Class<?> itf : itfs) {
+                        v = lookup(itf, registry);
+                        if (v != null) {
+                            break;
+                        }
+                    }
+                }
+            }
+            if (v != null) {
+                registry.put(key.getName(), v);
+            }
+        }
+        return v;
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassLookup.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassLookup.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassNameRegistry.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassNameRegistry.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassNameRegistry.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassNameRegistry.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,30 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.common;
+
+/**
+ *
+ */
+public interface ClassNameRegistry {
+
+    void put(String className, Object value);
+
+    Object get(String className);
+
+    Class<?> loadClass(String className);
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassNameRegistry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassNameRegistry.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassRegistry.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassRegistry.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassRegistry.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassRegistry.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,28 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.common;
+
+/**
+ *
+ */
+public interface ClassRegistry {
+
+    void put(Class<?> clazz, Object value);
+
+    Object get(Class<?> clazz);
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassRegistry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/ClassRegistry.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/DateParser.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/DateParser.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/DateParser.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/DateParser.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,257 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Alejandro Abdelnur, Sun Microsystems
+ */
+package org.apache.chemistry.atompub.client.common;
+
+import java.text.DateFormat;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * A helper class that parses Dates out of Strings with date time in RFC822 and
+ * W3CDateTime formats plus the variants Atom (0.3) and RSS (0.9, 0.91, 0.92,
+ * 0.93, 0.94, 1.0 and 2.0) specificators added to those formats.
+ * <p>
+ * It uses the JDK java.text.SimpleDateFormat class attemtping the parse using a
+ * mask for each one of the possible formats.
+ */
+public class DateParser {
+
+    // order is like this because the SimpleDateFormat.parse does not fail with
+    // exception if it can parse a valid date out of a substring of the full
+    // string given the mask so we have to check the most complete format first,
+    // then it fails with exception
+    private static final String[] RFC822_MASKS = { "EEE, dd MMM yy HH:mm:ss z",
+            "EEE, dd MMM yy HH:mm z", "dd MMM yy HH:mm:ss z",
+            "dd MMM yy HH:mm z" };
+
+    // order is like this because the SimpleDateFormat.parse does not fail with
+    // exception if it can parse a valid date out of a substring of the full
+    // string given the mask so we have to check the most complete format first,
+    // then it fails with exception
+    private static final String[] W3CDATETIME_MASKS = {
+            "yyyy-MM-dd'T'HH:mm:ss.SSSz", "yyyy-MM-dd't'HH:mm:ss.SSSz",
+            "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd't'HH:mm:ss.SSS'z'",
+            "yyyy-MM-dd'T'HH:mm:ssz",
+            "yyyy-MM-dd't'HH:mm:ssz",
+            "yyyy-MM-dd'T'HH:mm:ss'Z'",
+            "yyyy-MM-dd't'HH:mm:ss'z'",
+            "yyyy-MM-dd'T'HH:mmz", // together with logic in the
+            // parseW3CDateTime they
+            "yyyy-MM'T'HH:mmz", // handle W3C dates without time forcing them to
+            // be GMT
+            "yyyy'T'HH:mmz", "yyyy-MM-dd't'HH:mmz", "yyyy-MM-dd'T'HH:mm'Z'",
+            "yyyy-MM-dd't'HH:mm'z'", "yyyy-MM-dd", "yyyy-MM", "yyyy" };
+
+    /**
+     * The masks used to validate and parse the input to this Atom date. These
+     * are a lot more forgiving than what the Atom spec allows. The forms that
+     * are invalid according to the spec are indicated.
+     */
+    private static final String[] masks = { "yyyy-MM-dd'T'HH:mm:ss.SSSz",
+            "yyyy-MM-dd't'HH:mm:ss.SSSz", // invalid
+            "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd't'HH:mm:ss.SSS'z'", // invalid
+            "yyyy-MM-dd'T'HH:mm:ssz", "yyyy-MM-dd't'HH:mm:ssz", // invalid
+            "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd't'HH:mm:ss'z'", // invalid
+            "yyyy-MM-dd'T'HH:mmz", // invalid
+            "yyyy-MM-dd't'HH:mmz", // invalid
+            "yyyy-MM-dd'T'HH:mm'Z'", // invalid
+            "yyyy-MM-dd't'HH:mm'z'", // invalid
+            "yyyy-MM-dd", "yyyy-MM", "yyyy" };
+
+    /**
+     * Private constructor to avoid DateParser instances creation.
+     */
+    private DateParser() {
+    }
+
+    /**
+     * Parses a Date out of a string using an array of masks.
+     * <p>
+     * It uses the masks in order until one of them succedes or all fail.
+     * <p>
+     *
+     * @param masks array of masks to use for parsing the string
+     * @param sDate string to parse for a date.
+     * @return the Date represented by the given string using one of the given
+     *         masks. It returns <b>null</b> if it was not possible to parse the
+     *         the string with any of the masks.
+     *
+     */
+    private static Date parseUsingMask(String[] masks, String sDate) {
+        sDate = (sDate != null) ? sDate.trim() : null;
+        Date d = null;
+        for (int i = 0; d == null && i < masks.length; i++) {
+            DateFormat df = new SimpleDateFormat(masks[i], Locale.US);
+            // df.setLenient(false);
+            df.setLenient(true);
+            try {
+                ParsePosition pp = new ParsePosition(0);
+                d = df.parse(sDate, pp);
+                if (pp.getIndex() != sDate.length()) {
+                    d = null;
+                }
+                // System.out.println("pp["+pp.getIndex()+"] s["+sDate+" m["+masks[i]+"] d["+d+"]");
+            } catch (Exception ex1) {
+                // System.out.println("s: "+sDate+" m: "+masks[i]+" d: "+null);
+            }
+        }
+        return d;
+    }
+
+    /**
+     * Parses a Date out of a String with a date in RFC822 format.
+     * <p>
+     * It parsers the following formats:
+     * <ul>
+     * <li>"EEE, dd MMM yyyy HH:mm:ss z"</li>
+     * <li>"EEE, dd MMM yyyy HH:mm z"</li>
+     * <li>"EEE, dd MMM yy HH:mm:ss z"</li>
+     * <li>"EEE, dd MMM yy HH:mm z"</li>
+     * <li>"dd MMM yyyy HH:mm:ss z"</li>
+     * <li>"dd MMM yyyy HH:mm z"</li>
+     * <li>"dd MMM yy HH:mm:ss z"</li>
+     * <li>"dd MMM yy HH:mm z"</li>
+     * </ul>
+     * <p>
+     * Refer to the java.text.SimpleDateFormat javadocs for details on the
+     * format of each element.
+     * <p>
+     *
+     * @param sDate string to parse for a date.
+     * @return the Date represented by the given RFC822 string. It returns
+     *         <b>null</b> if it was not possible to parse the given string into
+     *         a Date.
+     *
+     */
+    public static Date parseRFC822(String sDate) {
+        int utIndex = sDate.indexOf(" UT");
+        if (utIndex > -1) {
+            String pre = sDate.substring(0, utIndex);
+            String post = sDate.substring(utIndex + 3);
+            sDate = pre + " GMT" + post;
+        }
+        return parseUsingMask(RFC822_MASKS, sDate);
+    }
+
+    /**
+     * Parses a Date out of a String with a date in W3C date-time format.
+     * <p>
+     * It parsers the following formats:
+     * <ul>
+     * <li>"yyyy-MM-dd'T'HH:mm:ssz"</li>
+     * <li>"yyyy-MM-dd'T'HH:mmz"</li>
+     * <li>"yyyy-MM-dd"</li>
+     * <li>"yyyy-MM"</li>
+     * <li>"yyyy"</li>
+     * </ul>
+     * <p>
+     * Refer to the java.text.SimpleDateFormat javadocs for details on the
+     * format of each element.
+     * <p>
+     *
+     * @param sDate string to parse for a date.
+     * @return the Date represented by the given W3C date-time string. It
+     *         returns null if it was not possible to parse the given string
+     *         into a Date.
+     *
+     */
+    public static Date parseW3CDateTime(String sDate) {
+        if (sDate == null) {
+            return null;
+        }
+        // if sDate has time on it, it injects 'GTM' before de TZ displacement
+        // to
+        // allow the SimpleDateFormat parser to parse it properly
+        int tIndex = sDate.indexOf("T");
+        if (tIndex > -1) {
+            if (sDate.endsWith("Z")) {
+                sDate = sDate.substring(0, sDate.length() - 1) + "+00:00";
+            }
+            int tzdIndex = sDate.indexOf("+", tIndex);
+            if (tzdIndex == -1) {
+                tzdIndex = sDate.indexOf("-", tIndex);
+            }
+            if (tzdIndex > -1) {
+                String pre = sDate.substring(0, tzdIndex);
+                int secFraction = pre.indexOf(",");
+                if (secFraction > -1) {
+                    pre = pre.substring(0, secFraction);
+                }
+                String post = sDate.substring(tzdIndex);
+                sDate = pre + "GMT" + post;
+            }
+        } else {
+            sDate += "T00:00GMT";
+        }
+        return parseUsingMask(W3CDATETIME_MASKS, sDate);
+    }
+
+    /**
+     * Parses a Date out of a String with a date in W3C date-time format or in a
+     * RFC822 format.
+     *
+     * @param sDate string to parse for a date.
+     * @return the Date represented by the given W3C date-time string, or null
+     *         if it was not possible to parse the given string into a Date.
+     */
+    public static Date parseDate(String sDate) {
+        if (sDate == null) {
+            return null;
+        }
+        Date d = parseW3CDateTime(sDate);
+        if (d == null) {
+            d = parseRFC822(sDate);
+        }
+        return d;
+    }
+
+    /**
+     * Creates a RFC822 representation of a date.
+     * <p>
+     * Refer to the java.text.SimpleDateFormat javadocs for details on the
+     * format of each element.
+     *
+     * @param date Date to format
+     * @return the RFC822 representation of the given Date,
+     */
+    public static String formatRFC822(Date date) {
+        SimpleDateFormat dateFormater = new SimpleDateFormat(
+                "EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
+        dateFormater.setTimeZone(TimeZone.getTimeZone("GMT"));
+        return dateFormater.format(date);
+    }
+
+    /**
+     * Creates a W3C Date Time representation of a date.
+     * <p>
+     * Refer to the java.text.SimpleDateFormat javadocs for details on the
+     * format of each element.
+     *
+     * @param date Date to format
+     * @return the W3C Date Time representation of the given Date
+     */
+    public static String formatW3CDateTime(Date date) {
+        SimpleDateFormat dateFormater = new SimpleDateFormat(
+                "yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
+        dateFormater.setTimeZone(TimeZone.getTimeZone("GMT"));
+        return dateFormater.format(date);
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/DateParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/DateParser.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/Path.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/Path.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/Path.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/Path.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,552 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.common;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ */
+public class Path implements Serializable {
+
+    public static final char SEP = '/';
+
+    protected static final int HAS_LEADING = 1;
+
+    protected static final int HAS_TRAILING = 2;
+
+    protected static final int HASH_MASK = ~HAS_TRAILING;
+
+    protected static final int ALL_SEPARATORS = HAS_LEADING | HAS_TRAILING;
+
+    protected static final int USED_BITS = 2;
+
+    protected static final String[] NO_SEGMENTS = new String[0];
+
+    private static final long serialVersionUID = 5008948361159403627L;
+
+    public static final Path EMPTY = new Path(new String[0], 0) {
+        private static final long serialVersionUID = -1731993368728652448L;
+
+        @Override
+        public String toString() {
+            return "";
+        }
+    };
+
+    public static final Path ROOT = new Path(new String[0], 1) {
+        private static final long serialVersionUID = -6689687769363666578L;
+
+        @Override
+        public String toString() {
+            return "/";
+        }
+    };
+
+    protected String[] segments;
+
+    protected int flags;
+
+    public Path(String path) {
+        init(path);
+        updateHashCode();
+    }
+
+    public Path(String path, int flags) {
+        init(path);
+        this.flags |= flags & ALL_SEPARATORS;
+        updateHashCode();
+    }
+
+    public Path(String[] segments, int flags) {
+        this.segments = segments;
+        this.flags = flags;
+        updateHashCode();
+    }
+
+    public Path(Path path) {
+        segments = path.segments;
+        flags = path.flags;
+    }
+
+    private void init(String path) {
+        List<String> segments = new ArrayList<String>();
+        int slash = 0;
+        int off = 0;
+        int cnt = 0;
+        int len = path.length();
+        if (len == 0) {
+            flags = 0;
+            this.segments = NO_SEGMENTS;
+            return;
+        }
+        if (len == 1) {
+            char c = path.charAt(0);
+            if (c == '/') {
+                flags = HAS_LEADING;
+                this.segments = NO_SEGMENTS;
+                return;
+            } else if (c == '.') {
+                flags = 0;
+                this.segments = NO_SEGMENTS;
+                return;
+            } else {
+                flags = 0;
+                this.segments = new String[] { path };
+                return;
+            }
+        }
+        char[] chars = path.toCharArray();
+        flags = chars[0] == '/' ? HAS_LEADING : 0;
+        if (chars[len - 1] == '/') {
+            flags |= HAS_TRAILING;
+        }
+        for (int i = 0; i < len; i++) {
+            char c = chars[i];
+            switch (c) {
+            case SEP:
+                if (slash == 0) { // first slash
+                    if (cnt > 0) { // segment end
+                        segments.add(new String(chars, off, cnt));
+                        cnt = 0;
+                    }
+                    off = i;
+                } else { // ignore double slashes
+                    off++;
+                }
+                slash++;
+                break;
+            case '.':
+                if (slash > 0 || i == 0) {
+                    if (i < chars.length - 2) { // look ahead 2 chars
+                        char c1 = chars[i + 1];
+                        char c2 = chars[i + 2];
+                        if (c1 == '.' && c2 == SEP) { // a .. segment
+                            if (segments.isEmpty()) { // add a dot segment
+                                segments.add("..");
+                            } else { // remove last segment
+                                int last = segments.size() - 1;
+                                if (!"..".equals(segments.get(last))) {
+                                    segments.remove(last);
+                                } else {
+                                    segments.add("..");
+                                }
+                            }
+                            i += 2;
+                            slash = 1;
+                            continue;
+                        } else if (c1 == SEP) { // a . segment - ignore it
+                            i++;
+                            slash = 1;
+                            continue;
+                        }
+                    } else if (i < chars.length - 1 && chars[i + 1] == '/') { // ignore
+                                                                              // .
+                                                                              // segment
+                        slash = 0;
+                        continue; // TODO - we may add here the segment to avoid
+                                  // rereading the char
+                    }
+                    slash = 0;
+                }
+                // do nothing (the char will be added to the segment)
+            default:
+                if (slash > 0) {
+                    slash = 0;
+                    off = i;
+                }
+                cnt++;
+                break;
+            }
+        }
+        if (cnt > 0) {
+            segments.add(new String(chars, off, cnt));
+        }
+        int size = segments.size();
+        if (size == 0) {
+            this.segments = NO_SEGMENTS;
+        } else {
+            this.segments = segments.toArray(new String[segments.size()]);
+        }
+    }
+
+    protected final void updateHashCode() {
+        flags = (flags & ALL_SEPARATORS) | (computeHashCode() << USED_BITS);
+    }
+
+    protected int computeHashCode() {
+        int hash = 17;
+        int segmentCount = segments.length;
+        for (int i = 0; i < segmentCount; i++) {
+            // this function tends to given a fairly even distribution
+            hash = hash * 37 + segments[i].hashCode();
+        }
+        return hash;
+    }
+
+    public boolean isAbsolute() {
+        return (flags & HAS_LEADING) != 0;
+    }
+
+    public boolean isRelative() {
+        return (flags & HAS_LEADING) == 0;
+    }
+
+    public boolean isRoot() {
+        return (segments.length == 0) && ((flags & HAS_LEADING) != 0);
+    }
+
+    public boolean isEmpty() {
+        return (segments.length == 0) && ((flags & HAS_LEADING) == 0);
+    }
+
+    public boolean hasTrailingSeparator() {
+        return (flags & HAS_TRAILING) != 0;
+    }
+
+    public int segmentCount() {
+        return segments.length;
+    }
+
+    public String[] segments() {
+        final String[] segmentCopy = new String[segments.length];
+        System.arraycopy(segments, 0, segmentCopy, 0, segments.length);
+        return segmentCopy;
+    }
+
+    public String segment(int index) {
+        return segments[index];
+    }
+
+    public String lastSegment() {
+        int len = segments.length;
+        return len == 0 ? null : segments[len - 1];
+    }
+
+    public String getFileExtension() {
+        int len = segments.length;
+        if (len == 0) {
+            return null;
+        }
+        String name = segments[len - 1];
+        int p = name.lastIndexOf('.');
+        if (p > -1) {
+            return name.substring(p + 1);
+        }
+        return null;
+    }
+
+    public String getFileName() {
+        int len = segments.length;
+        if (len == 0) {
+            return null;
+        }
+        String name = segments[len - 1];
+        int p = name.lastIndexOf('.');
+        if (p > -1) {
+            return name.substring(0, p);
+        }
+        return name;
+    }
+
+    public String[] getFileParts() {
+        int len = segments.length;
+        if (len == 0) {
+            return null;
+        }
+        String name = segments[len - 1];
+        int p = name.lastIndexOf('.');
+        if (p > -1) {
+            return new String[] { name.substring(0, p), name.substring(p + 1) };
+        }
+        return new String[] { name, null };
+    }
+
+    public Path makeAbsolute() {
+        if (isAbsolute()) {
+            return this;
+        }
+        int k = 0;
+        for (int i = 0; i < segments.length; i++) {
+            if ("..".equals(segments[i])) {
+                k++;
+            } else {
+                break;
+            }
+        }
+        if (k > 0) {
+            String[] newSegments = new String[segments.length - k];
+            System.arraycopy(segments, k, newSegments, 0, newSegments.length);
+            return new Path(newSegments, flags | HAS_LEADING);
+        }
+        return new Path(segments, flags | HAS_LEADING);
+    }
+
+    public Path makeRelative() {
+        if (isRelative()) {
+            return this;
+        }
+        return new Path(segments, flags & ~HAS_LEADING);
+    }
+
+    public Path removeTrailingSeparator() {
+        if (!hasTrailingSeparator()) {
+            return this;
+        }
+        return new Path(segments, flags & ~HAS_TRAILING);
+    }
+
+    public Path addTrailingSeparator() {
+        if (hasTrailingSeparator()) {
+            return this;
+        }
+        return new Path(segments, flags | HAS_TRAILING);
+    }
+
+    public Path removeLastSegments(int count) {
+        if (count == 0) {
+            return this;
+        }
+        if (count >= segments.length) {
+            // result will have no trailing separator
+            return (flags & HAS_LEADING) != 0 ? ROOT : EMPTY;
+        }
+        assert count > 0;
+        final int newSize = segments.length - count;
+        final String[] newSegments = new String[newSize];
+        System.arraycopy(segments, 0, newSegments, 0, newSize);
+        return new Path(newSegments, flags);
+    }
+
+    public Path removeFirstSegments(int count) {
+        if (count == 0) {
+            return this;
+        }
+        if (count >= segments.length) {
+            return EMPTY;
+        }
+        assert count > 0;
+        int newSize = segments.length - count;
+        String[] newSegments = new String[newSize];
+        System.arraycopy(segments, count, newSegments, 0, newSize);
+
+        // result is always a relative path
+        return new Path(newSegments, flags & HAS_TRAILING);
+    }
+
+    public Path removeFileExtension() {
+        String extension = getFileExtension();
+        if (extension == null || extension.equals("")) { //$NON-NLS-1$
+            return this;
+        }
+        String lastSegment = lastSegment();
+        int index = lastSegment.lastIndexOf(extension) - 1;
+        return removeLastSegments(1).append(lastSegment.substring(0, index));
+    }
+
+    public Path up() {
+        return removeLastSegments(1);
+    }
+
+    public Path getParent() {
+        return removeLastSegments(1);
+    }
+
+    public Path appendSegment(String segment) {
+        int myLen = segments.length;
+        String[] newSegments = new String[myLen + 1];
+        System.arraycopy(segments, 0, newSegments, 0, myLen);
+        newSegments[myLen] = segment;
+        return new Path(newSegments, flags);
+    }
+
+    public Path append(Path tail) {
+        // optimize some easy cases
+        if (tail == null || tail.segmentCount() == 0) {
+            return this;
+        }
+        if (isEmpty()) {
+            return tail.makeRelative();
+        }
+        if (isRoot()) {
+            return tail.makeAbsolute();
+        }
+
+        int flags = this.flags;
+
+        int myLen = segments.length;
+        int tailLen = tail.segmentCount();
+        int j = 0;
+        int s = 0;
+        // remove ../ segments from the appended path
+        for (int i = 0; i < tailLen; i++) {
+            String seg = tail.segments[i];
+            if ("..".equals(seg)) {
+                j++;
+            } else if (".".equals(seg)) {
+                if (j == 0)
+                    s++;
+            } else {
+                break;
+            }
+        }
+        if (j > 0)
+            s = j;
+
+        int k = myLen - j;
+        if (k < 0) {
+            myLen = -k;
+        } else {
+            myLen = k;
+        }
+
+        // concatenate the two segment arrays
+        String[] newSegments = new String[myLen + tailLen - s];
+        if (k < 0) {
+            for (int i = 0; i < myLen; i++) {
+                newSegments[i] = "..";
+            }
+            flags &= ~HAS_LEADING;
+        } else if (k > 0) {
+            System.arraycopy(segments, 0, newSegments, 0, myLen);
+        }
+        for (int i = s; i < tailLen; i++) {
+            newSegments[myLen + i - s] = tail.segment(i);
+        }
+        // use my leading separators and the tail's trailing separator
+
+        return new Path(newSegments, (flags & HAS_LEADING)
+                | (tail.hasTrailingSeparator() ? HAS_TRAILING : 0));
+    }
+
+    public Path append(String tail) {
+        // optimize addition of a single segment
+        if (tail.indexOf(SEP) == -1) {
+            int tailLength = tail.length();
+            if (tailLength < 3) {
+                // some special cases
+                if (tailLength == 0 || ".".equals(tail)) {
+                    return this;
+                }
+                if ("..".equals(tail)) {
+                    return removeLastSegments(1);
+                }
+            }
+            // just add the segment
+            int myLen = segments.length;
+            String[] newSegments = new String[myLen + 1];
+            System.arraycopy(segments, 0, newSegments, 0, myLen);
+            newSegments[myLen] = tail;
+            return new Path(newSegments, flags & ~HAS_TRAILING);
+        }
+        // go with easy implementation
+        return append(new Path(tail));
+    }
+
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof Path)) {
+            return false;
+        }
+        Path target = (Path) obj;
+        // check leading separators and hash code
+        if (flags != target.flags) {
+            return false;
+        }
+        String[] targetSegments = target.segments;
+        int i = segments.length;
+        // check segment count
+        if (i != targetSegments.length) {
+            return false;
+        }
+        // check segments in reverse order - later segments more likely to
+        // differ
+        while (--i >= 0) {
+            if (!segments[i].equals(targetSegments[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return flags & HASH_MASK;
+    }
+
+    @Override
+    public String toString() {
+        int len = segments.length;
+        if (len == 0) {
+            return (flags & HAS_LEADING) != 0 ? "/" : "";
+        }
+        StringBuilder buf = new StringBuilder(len * 16);
+        if ((flags & HAS_LEADING) != 0) {
+            buf.append(SEP);
+        }
+        buf.append(segments[0]);
+        for (int i = 1; i < len; i++) {
+            buf.append(SEP).append(segments[i]);
+        }
+        if ((flags & HAS_TRAILING) != 0) {
+            buf.append(SEP);
+        }
+        return buf.toString();
+    }
+
+    public static void main(String[] args) {
+        //
+        // System.out.println(new Path("abc/asdf/file.ext"));
+        // System.out.println(new
+        // org.nuxeo.common.utils.Path("abc/asdf/file.ext"));
+        //
+        // System.out.println(new Path("/abc/asdf/file.ext"));
+        // System.out.println(new
+        // org.nuxeo.common.utils.Path("/abc/asdf/file.ext"));
+        //
+        // System.out.println(new Path("/./abc//asdf/../file.ext"));
+        // System.out.println(new
+        // org.nuxeo.common.utils.Path("/./abc//asdf/../file.ext"));
+        //
+        // System.out.println("----------------------");
+        //
+        // double s = System.currentTimeMillis();
+        // for (int i=0; i<100000; i++) {
+        // new Path("/./abc//asdf/../file.ext");
+        // }
+        // System.out.println("new path: >>>> "+(System.currentTimeMillis()-s)/1000);
+        //
+        // s = System.currentTimeMillis();
+        // for (int i=0; i<100000; i++) {
+        // new org.nuxeo.common.utils.Path("/./abc//asdf/../file.ext");
+        // }
+        // System.out.println("old path: >>>> "+(System.currentTimeMillis()-s)/1000);
+
+        Path p = new Path("/commands");
+        System.out.println(p);
+        System.out.println(p = p.append("test"));
+        System.out.println(p = p.append("../../../test2"));
+        System.out.println(p = p.makeAbsolute());
+        // System.out.println(p=p.append(".."));
+        // System.out.println(p=p.append(".."));
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/Path.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/Path.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/ATOM.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/ATOM.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/ATOM.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/ATOM.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,37 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.common.atom;
+
+import javax.xml.namespace.QName;
+
+/**
+ *
+ */
+public interface ATOM {
+
+    public final static String APP_NS = "http://www.w3.org/2007/app";
+
+    public final static String ATOM_NS = "http://www.w3.org/2005/Atom";
+
+    public final static QName FEED = new QName(ATOM_NS, "feed");
+
+    public final static QName ENTRY = new QName(ATOM_NS, "entry");
+
+    public final static QName LINK = new QName(ATOM_NS, "link");
+
+    public final static QName COLLECTION = new QName(APP_NS, "collection");
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/ATOM.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/ATOM.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractEntryReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractEntryReader.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractEntryReader.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractEntryReader.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,108 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.common.atom;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.chemistry.atompub.CMIS;
+import org.apache.chemistry.atompub.client.common.xml.ChildrenNavigator;
+import org.apache.chemistry.atompub.client.common.xml.StaxReader;
+
+/**
+ *
+ */
+public abstract class AbstractEntryReader<T> implements EntryReader<T>, ATOM {
+
+    protected abstract T createObject(ReadContext ctx);
+
+    public T read(ReadContext ctx, File file) throws XMLStreamException,
+            IOException {
+        InputStream in = new FileInputStream(file);
+        try {
+            return read(ctx, in);
+        } finally {
+            in.close();
+        }
+    }
+
+    public T read(ReadContext ctx, URL url) throws XMLStreamException,
+            IOException {
+        InputStream in = url.openStream();
+        try {
+            return read(ctx, in);
+        } finally {
+            in.close();
+        }
+    }
+
+    public T read(ReadContext ctx, InputStream in) throws XMLStreamException {
+        return read(ctx, StaxReader.newReader(in));
+    }
+
+    public T read(ReadContext ctx, XMLStreamReader reader)
+            throws XMLStreamException {
+        return read(ctx, StaxReader.newReader(reader));
+    }
+
+    public T read(ReadContext ctx, StaxReader reader) throws XMLStreamException {
+        if (!reader.getFirstTag(ATOM.ENTRY)) {
+            return null;
+        }
+        T object = createObject(ctx);
+        ChildrenNavigator children = reader.getChildren();
+        while (children.next()) {
+            if (reader.getNamespaceURI().equals(CMIS.CMIS_NS)) {
+                readCmisElement(ctx, reader, object);
+            } else {
+                readEntryElement(ctx, reader, object);
+            }
+        }
+        return object;
+    }
+
+    protected void readCmisElement(ReadContext ctx, StaxReader reader, T object)
+            throws XMLStreamException {
+        // do nothing
+    }
+
+    protected void readEntryElement(ReadContext ctx, StaxReader reader, T object)
+            throws XMLStreamException {
+        if (reader.getNamespaceURI().equals(ATOM.ATOM_NS)) {
+            readAtomElement(ctx, reader, object);
+        } else {
+            readExtensionElement(ctx, reader, object);
+        }
+    }
+
+    protected void readAtomElement(ReadContext ctx, StaxReader reader, T object)
+            throws XMLStreamException {
+        // do nothing
+    }
+
+    protected void readExtensionElement(ReadContext ctx, StaxReader reader,
+            T object) throws XMLStreamException {
+        // do nothing
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractEntryReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractEntryReader.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractFeedReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractFeedReader.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractFeedReader.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractFeedReader.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,129 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.common.atom;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URL;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.chemistry.atompub.client.common.xml.ChildrenNavigator;
+import org.apache.chemistry.atompub.client.common.xml.StaxReader;
+
+/**
+ *
+ */
+public abstract class AbstractFeedReader<T, E> implements FeedReader<T>, ATOM {
+
+    protected EntryReader<E> entryBuilder;
+
+    protected abstract T createFeed(StaxReader reader);
+
+    protected abstract void addEntry(T feed, E entry);
+
+    protected AbstractFeedReader(EntryReader<E> entryBuilder) {
+        this.entryBuilder = entryBuilder;
+    }
+
+    public EntryReader<E> getEntryBuilder() {
+        return entryBuilder;
+    }
+
+    public void setEntryBuilder(EntryReader<E> entryBuilder) {
+        this.entryBuilder = entryBuilder;
+    }
+
+    public T read(ReadContext ctx, File file) throws XMLStreamException,
+            IOException {
+        InputStream in = new FileInputStream(file);
+        try {
+            return read(ctx, in);
+        } finally {
+            in.close();
+        }
+    }
+
+    public T read(ReadContext ctx, URL url) throws XMLStreamException,
+            IOException {
+        InputStream in = url.openStream();
+        try {
+            return read(ctx, in);
+        } finally {
+            in.close();
+        }
+    }
+
+    public T read(ReadContext ctx, InputStream in) throws XMLStreamException {
+        StaxReader xr = StaxReader.newReader(in);
+        try {
+            return read(ctx, xr);
+        } finally {
+            xr.close();
+        }
+    }
+
+    public T read(ReadContext ctx, Reader reader) throws XMLStreamException {
+        StaxReader xr = StaxReader.newReader(reader);
+        try {
+            return read(ctx, xr);
+        } finally {
+            xr.close();
+        }
+    }
+
+    public T read(ReadContext ctx, StaxReader reader) throws XMLStreamException {
+        if (!reader.getFirstTag(ATOM.FEED)) {
+            throw new XMLStreamException("Parse error: Not an atom feed");
+        }
+        // create a new feed object to be filled
+        T feed = createFeed(reader);
+        ChildrenNavigator nav = reader.getChildren();
+        while (nav.next() && !isDone(ctx, reader)) {
+            String nsUri = reader.getNamespaceURI();
+            if (ATOM.ATOM_NS.equals(nsUri)) {
+                if ("entry".equals(reader.getLocalName())) {
+                    addEntry(feed, entryBuilder.read(ctx, reader));
+                } else {
+                    readAtomElement(ctx, reader, nsUri, feed);
+                }
+            } else {
+                readExtensionElement(ctx, reader, nsUri, feed);
+            }
+        }
+        return feed;
+    }
+
+    protected boolean isDone(ReadContext ctx, StaxReader reader)
+            throws XMLStreamException {
+        return false;
+    }
+
+    protected void readAtomElement(ReadContext ctx, StaxReader reader,
+            String nsUri, T feed) throws XMLStreamException {
+    }
+
+    protected void readExtensionElement(ReadContext ctx, StaxReader reader,
+            String nsUri, T feed) throws XMLStreamException {
+    }
+
+    /** entry builder */
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractFeedReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractFeedReader.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractObjectReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractObjectReader.java?rev=781949&view=auto
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractObjectReader.java (added)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractObjectReader.java Fri Jun  5 09:05:20 2009
@@ -0,0 +1,132 @@
+/*
+ * Licensed 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.
+ *
+ * Authors:
+ *     Bogdan Stefanescu, Nuxeo
+ */
+package org.apache.chemistry.atompub.client.common.atom;
+
+import java.util.ArrayList;
+
+import javax.xml.stream.XMLStreamException;
+
+import org.apache.chemistry.Property;
+import org.apache.chemistry.Type;
+import org.apache.chemistry.atompub.CMIS;
+import org.apache.chemistry.atompub.client.common.xml.ChildrenNavigator;
+import org.apache.chemistry.atompub.client.common.xml.ParseException;
+import org.apache.chemistry.atompub.client.common.xml.StaxReader;
+
+/**
+ *
+ */
+public abstract class AbstractObjectReader<T> extends AbstractEntryReader<T> {
+
+    protected abstract void readProperty(ReadContext ctx, StaxReader reader,
+            T object, XmlProperty p);
+
+    @Override
+    protected void readCmisElement(ReadContext ctx, StaxReader reader, T object)
+            throws XMLStreamException {
+        if (reader.getLocalName().equals(CMIS.OBJECT.getLocalPart())) {
+            readCmisObject(ctx, reader, object);
+        }
+    }
+
+    protected void readCmisObject(ReadContext ctx, StaxReader reader, T object)
+            throws XMLStreamException {
+        ChildrenNavigator children = reader.getChildren();
+        while (children.next()) {
+            readObjectChildElement(ctx, reader, object);
+        }
+    }
+
+    protected void readObjectChildElement(ReadContext ctx, StaxReader reader,
+            T object) throws XMLStreamException {
+        if (reader.getNamespaceURI().equals(CMIS.OBJECT.getNamespaceURI())) {
+            if (reader.getLocalName().equals(CMIS.PROPERTIES.getLocalPart())) {
+                readProperties(ctx, reader, object);
+            } else if (reader.getLocalName().equals(
+                    CMIS.ALLOWABLE_ACTIONS.getLocalPart())) {
+                readAllowableActions(ctx, reader, object);
+            } else { // unknown tag
+                readOtherCmisElement(ctx, reader, object);
+            }
+        } else {
+            readEntryElement(ctx, reader, object);
+        }
+    }
+
+    protected void readProperties(ReadContext ctx, StaxReader reader, T object)
+            throws XMLStreamException {
+        PropertyIterator it = new PropertyIterator(reader);
+        ArrayList<XmlProperty> prefetch = null;
+        Type entryType = ctx.getType();
+        if (entryType == null) {
+            prefetch = new ArrayList<XmlProperty>();
+            while (it.hasNext()) {
+                XmlProperty p = it.next();
+                // System.out.println(" prefetch >>>>> "+reader.getName()+" -> "+p.value);
+                if (Property.TYPE_ID.equals(p.value)) {
+                    entryType = ctx.getRepository().getType(
+                            (String) p.getXmlValue());
+                    if (entryType == null) {
+                        throw new ParseException("No such type: " + p.value);
+                    }
+                    prefetch.add(p);
+                    break;
+                } else {
+                    prefetch.add(p);
+                }
+            }
+            if (entryType == null) {
+                throw new IllegalStateException("Type not known");
+            }
+        }
+        if (prefetch != null) {
+            for (XmlProperty p : prefetch) {
+                p.def = entryType.getPropertyDefinition((String) p.value);
+                if (p.def == null) {
+                    throw new ParseException("No such property definition: "
+                            + p.value + " in type " + entryType);
+                }
+                p.value = XmlProperty.NULL;
+                // System.out.println("adding prefetched >>>>> "+reader.getName()+" -> "+p.getXmlValue());
+                readProperty(ctx, reader, object, p);
+            }
+        }
+        // consume the rest of the stream
+        while (it.hasNext()) {
+            XmlProperty p = it.next();
+            p.def = entryType.getPropertyDefinition((String) p.value);
+            if (p.def == null) {
+                throw new ParseException("No such property definition: "
+                        + p.value + " in type " + entryType);
+            }
+            p.value = XmlProperty.NULL;
+            // System.out.println("adding non prefetched >>>>> "+reader.getName()+" -> "+p.getXmlValue());
+            readProperty(ctx, reader, object, p);
+        }
+    }
+
+    protected void readAllowableActions(ReadContext ctx, StaxReader reader,
+            T object) throws XMLStreamException {
+        // TODO not yet implemented
+    }
+
+    protected void readOtherCmisElement(ReadContext ctx, StaxReader reader,
+            T object) throws XMLStreamException {
+        // do nothing
+    }
+
+}

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractObjectReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/common/atom/AbstractObjectReader.java
------------------------------------------------------------------------------
    svn:keywords = Id