You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2007/08/21 02:51:29 UTC
svn commit: r567888 [2/4] - in /incubator/abdera/java/trunk: ./ build/
extensions/ extensions/gdata/ extensions/gdata/src/
extensions/gdata/src/main/ extensions/gdata/src/main/java/
extensions/gdata/src/main/java/org/ extensions/gdata/src/main/java/org...
Added: incubator/abdera/java/trunk/extensions/geo/src/main/java/org/apache/abdera/ext/geo/Polygon.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/geo/src/main/java/org/apache/abdera/ext/geo/Polygon.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/geo/src/main/java/org/apache/abdera/ext/geo/Polygon.java (added)
+++ incubator/abdera/java/trunk/extensions/geo/src/main/java/org/apache/abdera/ext/geo/Polygon.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,78 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.geo;
+
+public class Polygon
+ extends Multiple {
+
+ private static final long serialVersionUID = 5387230171535985909L;
+
+ public Polygon() {
+ super();
+ }
+
+ public Polygon(Multiple multiple) {
+ super(multiple);
+ verify();
+ }
+
+ public Polygon(Point point) {
+ super(point);
+ verify();
+ }
+
+ public Polygon(Coordinate... coordinates) {
+ super(coordinates);
+ verify();
+ }
+
+ public Polygon(Coordinates coordinates) {
+ super(coordinates);
+ verify();
+ }
+
+ public Polygon(String value) {
+ super(value);
+ verify();
+ }
+
+ public Polygon(Multiple... multiples) {
+ super(multiples);
+ verify();
+ }
+
+ public Polygon(Point... points) {
+ super(points);
+ verify();
+ }
+
+ public Polygon(double... values) {
+ super(values);
+ verify();
+ }
+
+ @Override
+ public void setCoordinates(Coordinates coordinates) {
+ super.setCoordinates(coordinates);
+ verify();
+ }
+
+ public void verify() {
+ super.verify179Rule();
+ }
+}
Added: incubator/abdera/java/trunk/extensions/geo/src/main/java/org/apache/abdera/ext/geo/Position.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/geo/src/main/java/org/apache/abdera/ext/geo/Position.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/geo/src/main/java/org/apache/abdera/ext/geo/Position.java (added)
+++ incubator/abdera/java/trunk/extensions/geo/src/main/java/org/apache/abdera/ext/geo/Position.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,132 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.geo;
+
+import java.io.Serializable;
+
+public abstract class Position
+ implements Serializable,
+ Cloneable,
+ Comparable<Position> {
+
+ public static final String DEFAULT_FEATURE_TYPE_TAG = "location";
+ public static final String DEFAULT_RELATIONSHIP_TAG = "is-located-at";
+
+ protected String featureTypeTag;
+ protected String relationshipTag;
+ protected Double elevation;
+ protected Double floor;
+ protected Double radius;
+
+ public Double getElevation() {
+ return elevation;
+ }
+ public void setElevation(Double elevation) {
+ this.elevation = elevation;
+ }
+ public String getFeatureTypeTag() {
+ return featureTypeTag;
+ }
+ public void setFeatureTypeTag(String featureTypeTag) {
+ this.featureTypeTag = featureTypeTag;
+ }
+ public Double getFloor() {
+ return floor;
+ }
+ public void setFloor(Double floor) {
+ this.floor = floor;
+ }
+ public Double getRadius() {
+ return radius;
+ }
+ public void setRadius(Double radius) {
+ this.radius = radius;
+ }
+ public String getRelationshipTag() {
+ return relationshipTag;
+ }
+ public void setRelationshipTag(String relationshipTag) {
+ this.relationshipTag = relationshipTag;
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ //int result = super.hashCode();
+ int result = this.getClass().hashCode();
+ result = PRIME * result + ((elevation == null) ? 0 : elevation.hashCode());
+ result = PRIME * result + ((featureTypeTag == null) ? DEFAULT_FEATURE_TYPE_TAG.hashCode() : featureTypeTag.hashCode());
+ result = PRIME * result + ((floor == null) ? 0 : floor.hashCode());
+ result = PRIME * result + ((radius == null) ? 0 : radius.hashCode());
+ result = PRIME * result + ((relationshipTag == null) ? DEFAULT_RELATIONSHIP_TAG.hashCode() : relationshipTag.hashCode());
+ return result;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (getClass() != obj.getClass())
+ return false;
+ final Position other = (Position) obj;
+ if (elevation == null) {
+ if (other.elevation != null)
+ return false;
+ } else if (!elevation.equals(other.elevation))
+ return false;
+ if (featureTypeTag == null) {
+ if (other.featureTypeTag != null &&
+ !other.featureTypeTag.equalsIgnoreCase(DEFAULT_FEATURE_TYPE_TAG))
+ return false;
+ } else {
+ String s = other.featureTypeTag != null ?
+ other.featureTypeTag : DEFAULT_FEATURE_TYPE_TAG;
+ if (!featureTypeTag.equalsIgnoreCase(s))
+ return false;
+ }
+ if (floor == null) {
+ if (other.floor != null)
+ return false;
+ } else if (!floor.equals(other.floor))
+ return false;
+ if (radius == null) {
+ if (other.radius != null)
+ return false;
+ } else if (!radius.equals(other.radius))
+ return false;
+ if (relationshipTag == null) {
+ if (other.relationshipTag != null &&
+ !other.relationshipTag.equalsIgnoreCase(DEFAULT_RELATIONSHIP_TAG))
+ return false;
+ } else {
+ String s = other.relationshipTag != null ?
+ other.relationshipTag : DEFAULT_RELATIONSHIP_TAG;
+ if (!relationshipTag.equalsIgnoreCase(s))
+ return false;
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Position>T clone() {
+ try {
+ return (T)super.clone();
+ } catch (CloneNotSupportedException e) {
+ return null; // should never happen
+ }
+ }
+}
Added: incubator/abdera/java/trunk/extensions/json/pom.xml
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/json/pom.xml?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/json/pom.xml (added)
+++ incubator/abdera/java/trunk/extensions/json/pom.xml Mon Aug 20 17:51:20 2007
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. 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. For additional information regarding
+ copyright in this work, please see the NOTICE file in the top level
+ directory of this distribution. -->
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>abdera</artifactId>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>abdera-extensions-json</artifactId>
+ <packaging>jar</packaging>
+ <name>Abdera Extensions - JSON</name>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ <description>Atom Specification Extensions - JSON</description>
+ <inceptionYear>2006</inceptionYear>
+ <url>http://incubator.apache.org/abdera</url>
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/abdera/java/trunk/extensions/json</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/abdera/java/trunk/extensions/json</developerConnection>
+ <url>http://svn.apache.org/repos/asf/incubator/abdera/java/trunk/extensions/json</url>
+ </scm>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>abdera-core</artifactId>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>abdera-parser</artifactId>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>abdera-protocol</artifactId>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>abdera-client</artifactId>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>json</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ws.commons.axiom</groupId>
+ <artifactId>axiom-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ws.commons.axiom</groupId>
+ <artifactId>axiom-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>stax</groupId>
+ <artifactId>stax-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+</project>
Added: incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONWriter.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONWriter.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONWriter.java (added)
+++ incubator/abdera/java/trunk/extensions/json/src/main/java/org/apache/abdera/ext/json/JSONWriter.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,298 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+
+package org.apache.abdera.ext.json;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+import org.apache.abdera.model.Base;
+import org.apache.abdera.model.Category;
+import org.apache.abdera.model.Collection;
+import org.apache.abdera.model.Content;
+import org.apache.abdera.model.Document;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.model.Generator;
+import org.apache.abdera.model.Link;
+import org.apache.abdera.model.Person;
+import org.apache.abdera.model.Service;
+import org.apache.abdera.model.Workspace;
+import org.apache.abdera.model.Content.Type;
+import org.apache.abdera.util.AbstractNamedWriter;
+import org.apache.abdera.util.AbstractWriterOptions;
+import org.apache.abdera.writer.NamedWriter;
+import org.apache.abdera.writer.WriterOptions;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class JSONWriter
+ extends AbstractNamedWriter
+ implements NamedWriter {
+
+ public static final String NAME = "json";
+
+ public static final String[] FORMATS = {
+ "application/json",
+ "application/javascript",
+ "application/ecmascript",
+ "text/javascript",
+ "text/ecmascript"
+ };
+
+ public JSONWriter() {
+ super(NAME,FORMATS);
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public Object write(Base base, WriterOptions options) throws IOException {
+ try {
+ return toJSON(base).toString();
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public void writeTo(Base base, OutputStream out, WriterOptions options) throws IOException {
+ try {
+ Object result = toJSON(base);
+ out.write(result.toString().getBytes());
+ if (options.getAutoClose()) out.close();
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public void writeTo(Base base, java.io.Writer out, WriterOptions options) throws IOException {
+ try {
+ Object result = toJSON(base);
+ out.write(result.toString());
+ if (options.getAutoClose()) out.close();
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public static Object toJSON(Object object) throws Exception {
+ if (object instanceof Feed) {
+ return toJSON((Feed) object);
+ } else if (object instanceof Entry) {
+ return toJSON((Entry) object);
+ } else if (object instanceof Service) {
+ return toJSON((Service) object);
+ } else if (object instanceof Document) {
+ return toJSON(((Document) object).getRoot());
+ }
+ return new IllegalArgumentException("Element is not supported by JSONWriter.");
+ }
+
+ public static JSONObject toJSON(Entry entry) throws Exception {
+ JSONObject jsentry = new JSONObject();
+ if (entry.getTitle() != null)
+ jsentry.put("title", entry.getTitle());
+
+ if (entry.getSummary() != null)
+ jsentry.put("summary", entry.getSummary());
+
+ if (entry.getId() != null)
+ jsentry.put("id", entry.getId().toString());
+
+ if (entry.getUpdated() != null)
+ jsentry.put("updated", entry.getUpdated().toString());
+
+ if (entry.getPublished() != null)
+ jsentry.put("published", entry.getPublished().toString());
+
+ jsentry.put("authors", personsToJSON(entry.getAuthors()));
+
+ jsentry.put("contributors", personsToJSON(entry.getContributors()));
+
+ jsentry.put("categories", categoriesToJSON(entry.getCategories()));
+
+ jsentry.put("links", linksToJSON(entry.getLinks()));
+
+ JSONObject jscontent = new JSONObject();
+ if (entry.getContentElement() != null) {
+
+ Content content = entry.getContentElement();
+ Type type = entry.getContentType();
+ if (type.equals(Content.Type.HTML) || type.equals(Content.Type.XHTML) || type.equals(Content.Type.TEXT)) {
+ jscontent.put("type", type.toString().toLowerCase());
+ } else {
+ jscontent.put("type", content.getMimeType().toString());
+ }
+ jscontent.put("value", content.getValue());;
+ jsentry.put("content", jscontent);
+ }
+
+ return jsentry;
+ }
+
+ public static JSONObject toJSON(Feed feed) throws Exception {
+ JSONObject jsfeed = new JSONObject();
+
+ if (feed.getGenerator() != null) {
+ Generator gen = feed.getGenerator();
+ JSONObject jsgen = new JSONObject();
+ jsgen.put("uri", gen.getUri().toString());
+ jsgen.put("value", gen.getText());
+ }
+
+ if (feed.getTitle() != null) {
+ jsfeed.put("title", feed.getTitle());
+ }
+
+ if (feed.getSubtitle() != null) {
+ jsfeed.put("subtitle", feed.getSubtitle());
+ }
+
+ if (feed.getId() != null) {
+ jsfeed.put("id", feed.getId().toString());
+ }
+
+ if (feed.getRights() != null) {
+ jsfeed.put("rights", feed.getRights());
+ }
+
+ if (feed.getLogo() != null) {
+ jsfeed.put("logo", feed.getLogo().toString());
+ }
+
+ if (feed.getIcon() != null) {
+ jsfeed.put("icon", feed.getIcon().toString());
+ }
+
+ if (feed.getUpdatedString() != null) {
+ jsfeed.put("updated", feed.getUpdatedString());
+ }
+
+ jsfeed.put("authors", personsToJSON(feed.getAuthors()));
+
+ jsfeed.put("contributors", personsToJSON(feed.getContributors()));
+
+ jsfeed.put("categories", categoriesToJSON(feed.getCategories()));
+
+ jsfeed.put("links", linksToJSON(feed.getLinks()));
+
+ JSONArray jsentries = new JSONArray();
+ List<Entry> entries = feed.getEntries();
+ for (Entry entry : entries) {
+ jsentries.put(toJSON(entry));
+ }
+
+ jsfeed.put("entries", jsentries);
+
+ return jsfeed;
+ }
+
+ public static JSONObject toJSON(Service service) throws Exception {
+ JSONObject jssvc = new JSONObject();
+ JSONArray jsworkspaces = new JSONArray();
+ List<Workspace> workspaces = service.getWorkspaces();
+ for (Workspace workspace : workspaces) {
+ JSONObject jsworkspace = new JSONObject();
+ JSONArray jscollections = new JSONArray();
+ jsworkspace.put("title", workspace.getTitle());
+ List<Collection> collections = workspace.getCollections();
+ for (Collection collection : collections) {
+ JSONObject jscollection = new JSONObject();
+ JSONArray jsaccepts = new JSONArray();
+ String[] accepts = collection.getAccept();
+ for (String accept : accepts) {
+ jsaccepts.put(accept);
+ }
+ jscollection.put("href", collection.getHref().toString());
+ jscollection.put("accept", jsaccepts);
+ jscollections.put(jscollection);
+ }
+ jsworkspace.put("collections", jscollections);
+ jsworkspaces.put(jsworkspace);
+ }
+ jssvc.put("workspaces", jsworkspaces);
+
+ return jssvc;
+ }
+
+ private static JSONArray categoriesToJSON(List<Category> categories) throws JSONException {
+ JSONArray jscategories = new JSONArray();
+ for (Category category : categories) {
+ if (category.getScheme() != null || category.getLabel() != null || category.getTerm() != null) {
+ JSONObject jscategory = new JSONObject();
+ if (category.getScheme() != null)
+ jscategory.put("scheme", category.getScheme().toString());
+
+ if (category.getTerm() != null)
+ jscategory.put("term", category.getTerm());
+
+ if (category.getLabel() != null)
+ jscategory.put("label", category.getLabel());
+ jscategories.put(jscategory);
+ }
+ }
+ return jscategories;
+ }
+
+ private static JSONArray personsToJSON(List<Person> persons) throws JSONException {
+ JSONArray jspersons = new JSONArray();
+ for (Person p : persons) {
+ if (p.getName() != null || p.getUri() != null || p.getEmail() != null) {
+ JSONObject jsperson = new JSONObject();
+ if (p.getName() != null)
+ jsperson.put("name", p.getName());
+ if (p.getUri() != null)
+ jsperson.put("uri", p.getUri().toString());
+ if (p.getEmail() != null)
+ jsperson.put("email", p.getEmail());
+ jspersons.put(jsperson);
+ }
+ }
+ return jspersons;
+ }
+
+ private static JSONArray linksToJSON(List<Link> links) throws JSONException {
+ JSONArray jslinks = new JSONArray();
+ for (Link link : links) {
+ JSONObject jslink = new JSONObject();
+ if (link.getHref() != null) {
+ jslink.put("href", link.getHref().toString());
+
+ if (link.getRel() != null)
+ jslink.put("rel", link.getRel());
+
+ if (link.getMimeType() != null)
+ jslink.put("type", link.getMimeType().getBaseType());
+
+ if (link.getHrefLang() != null)
+ jslink.put("hreflang", link.getHrefLang());
+ }
+ jslinks.put(jslink);
+ }
+ return jslinks;
+ }
+
+ @Override
+ protected WriterOptions initDefaultWriterOptions() {
+ return new AbstractWriterOptions() {};
+ }
+
+}
Added: incubator/abdera/java/trunk/extensions/json/src/main/resources/META-INF/services/org.apache.abdera.writer.NamedWriter
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/json/src/main/resources/META-INF/services/org.apache.abdera.writer.NamedWriter?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/json/src/main/resources/META-INF/services/org.apache.abdera.writer.NamedWriter (added)
+++ incubator/abdera/java/trunk/extensions/json/src/main/resources/META-INF/services/org.apache.abdera.writer.NamedWriter Mon Aug 20 17:51:20 2007
@@ -0,0 +1 @@
+org.apache.abdera.ext.json.JSONWriter
\ No newline at end of file
Added: incubator/abdera/java/trunk/extensions/main/pom.xml
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/pom.xml?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/pom.xml (added)
+++ incubator/abdera/java/trunk/extensions/main/pom.xml Mon Aug 20 17:51:20 2007
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. 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. For additional information regarding
+ copyright in this work, please see the NOTICE file in the top level
+ directory of this distribution. -->
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>abdera</artifactId>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>abdera-extensions-main</artifactId>
+ <packaging>jar</packaging>
+ <name>Abdera Extensions - Main</name>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ <description>Atom Specification Extensions - Main</description>
+ <inceptionYear>2006</inceptionYear>
+ <url>http://incubator.apache.org/abdera</url>
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/abdera/java/trunk/extensions/main</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/abdera/java/trunk/extensions/main</developerConnection>
+ <url>http://svn.apache.org/repos/asf/incubator/abdera/java/trunk/extensions/main</url>
+ </scm>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>abdera-core</artifactId>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>abdera-parser</artifactId>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>abdera-protocol</artifactId>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>abdera-client</artifactId>
+ <version>0.3.0-incubating-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.abdera</groupId>
+ <artifactId>json</artifactId>
+ <version>1.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ws.commons.axiom</groupId>
+ <artifactId>axiom-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ws.commons.axiom</groupId>
+ <artifactId>axiom-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>stax</groupId>
+ <artifactId>stax-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+</project>
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/bidi/BidiHelper.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/bidi/BidiHelper.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/bidi/BidiHelper.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/bidi/BidiHelper.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,308 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.bidi;
+
+import java.text.AttributedString;
+import java.text.Bidi;
+import java.util.Locale;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.model.Base;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.i18n.io.CharUtils;
+import org.apache.abdera.i18n.lang.Lang;
+
+/**
+ * <p>This is (hopefully) temporary. Ideally, this would be wrapped into the
+ * core model API so that the bidi stuff is handled seamlessly. There are
+ * still details being worked out on the Atom WG list and it's likely that
+ * at least one other impl (mozilla) will do something slightly different.</p>
+ *
+ * <p>Based on http://www.ietf.org/internet-drafts/draft-snell-atompub-bidi-04.txt</p>
+ *
+ * <p>Example:</p>
+ * <pre>
+ * <feed xmlns="http://www.w3.org/2005/Atom" dir="rtl">
+ * ...
+ * </feed>
+ * </pre>
+ *
+ * <p>The getBidi___ elements use the in-scope direction to wrap the text with
+ * the appropriate Unicode control characters. e.g. if dir="rtl", the text is
+ * wrapped with the RLE and PDF controls. If the text already contains the
+ * control chars, the dir attribute is ignored.</p>
+ *
+ * <pre>
+ * org.apache.abdera.Abdera abdera = new org.apache.abdera.Abdera();
+ * org.apache.abdera.model.Feed feed = abdera.getFactory().newFeed();
+ * feed.setAttributeValue("dir", "rtl");
+ * feed.setTitle("Testing");
+ * feed.addCategory("foo");
+ *
+ * System.out.println(
+ * BidiHelper.getBidiElementText(
+ * feed.getTitleElement()));
+ * System.out.println(
+ * BidiHelper.getBidiAttributeValue(
+ * feed.getCategories().get(0),"term"));
+ * </pre>
+ *
+ */
+public final class BidiHelper {
+
+ private static final QName DIR = new QName("dir");
+
+ BidiHelper() {}
+
+ public enum Direction { UNSPECIFIED, LTR, RTL};
+
+ /**
+ * Set the value of dir attribute
+ */
+ public static <T extends Element>void setDirection(
+ Direction direction,
+ T element) {
+ if (direction != Direction.UNSPECIFIED)
+ element.setAttributeValue(
+ DIR,
+ direction.toString().toLowerCase());
+ else if (direction == Direction.UNSPECIFIED)
+ element.setAttributeValue(DIR,"");
+ else if (direction == null)
+ element.removeAttribute(DIR);
+ }
+
+ /**
+ * Get the in-scope direction for an element.
+ */
+ public static <T extends Element>Direction getDirection(T element) {
+ Direction direction = Direction.UNSPECIFIED;
+ String dir = element.getAttributeValue("dir");
+ if (dir != null && dir.length() > 0)
+ direction = Direction.valueOf(dir.toUpperCase());
+ else if (dir == null) {
+ // if the direction is unspecified on this element,
+ // let's see if we've inherited it
+ Base parent = element.getParentElement();
+ if (parent != null &&
+ parent instanceof Element)
+ direction = getDirection((Element)parent);
+ }
+ return direction;
+ }
+
+ /**
+ * Return the specified text with appropriate Unicode Control Characters given
+ * the specified Direction.
+ * @param direction The Directionality of the text
+ * @param text The text to wrap within Unicode Control Characters
+ * @return The directionally-wrapped text
+ */
+ public static String getBidiText(Direction direction, String text) {
+ switch (direction) {
+ case LTR: return CharUtils.bidiLRE(text);
+ case RTL: return CharUtils.bidiRLE(text);
+ default: return text;
+ }
+ }
+
+ /**
+ * Return the textual content of a child element using the in-scope directionality
+ * @param element The parent element
+ * @param child The XML QName of the child element
+ * @return The directionally-wrapped text of the child element
+ */
+ public static <T extends Element>String getBidiChildText(T element, QName child) {
+ Element el = element.getFirstChild(child);
+ return (el != null) ? getBidiText(getDirection(el),el.getText()) : null;
+ }
+
+ /**
+ * Return the textual content of the specified element
+ * @param element An element containing directionally-sensitive text
+ * @return The directionally-wrapped text of the element
+ */
+ public static <T extends Element>String getBidiElementText(T element) {
+ return getBidiText(getDirection(element),element.getText());
+ }
+
+ /**
+ * Return the text content of the specified attribute using the in-scope directionality
+ * @param element The parent element
+ * @param name the name of the attribute
+ * @return The directionally-wrapped text of the attribute
+ */
+ public static <T extends Element>String getBidiAttributeValue(T element, String name) {
+ return getBidiText(getDirection(element),element.getAttributeValue(name));
+ }
+
+ /**
+ * Return the text content of the specified attribute using the in-scope directionality
+ * @param element The parent element
+ * @param name the name of the attribute
+ * @return The directionally-wrapped text of the attribute
+ */
+ public static <T extends Element>String getBidiAttributeValue(T element, QName name) {
+ return getBidiText(getDirection(element),element.getAttributeValue(name));
+ }
+
+
+ /**
+ * Attempt to guess the base direction using the in-scope language.
+ * Implements the method used by Internet Explorer 7's feed view
+ * documented here: http://blogs.msdn.com/rssteam/archive/2007/05/17/reading-feeds-in-right-to-left-order.aspx.
+ *
+ * This algorithm differs slightly from the method documented in that the
+ * primary language tag is case insensitive.
+ *
+ * If the language tag is not specified, then the default Locale is used to
+ * determine the direction.
+ *
+ * If the dir attribute is specified, the direction will be determine using it's value
+ * instead of the language
+ */
+ public static <T extends Element>Direction guessDirectionFromLanguage(T element) {
+ return guessDirectionFromLanguage(element, false);
+ }
+
+ /**
+ * Attempt to guess the base direction using the in-scope language.
+ * Implements the method used by Internet Explorer 7's feed view
+ * documented here: http://blogs.msdn.com/rssteam/archive/2007/05/17/reading-feeds-in-right-to-left-order.aspx.
+ *
+ * This algorithm differs slightly from the method documented in that the
+ * primary language tag is case insensitive.
+ *
+ * If the language tag is not specified, then the default Locale is used to
+ * determine the direction.
+ *
+ * According to the Atom Bidi spec, if the dir attribute is set explicitly, we
+ * should not do language guessing. This restriction can be bypassed by setting
+ * ignoredir to true.
+ */
+ public static <T extends Element>Direction guessDirectionFromLanguage(T element, boolean ignoredir) {
+ if (!ignoredir && hasDirection(element)) return getDirection(element);
+ Lang lang = element.getLanguageTag();
+ if (lang == null) {
+ Locale l = Locale.getDefault();
+ lang = new Lang(l.getLanguage());
+ }
+ String primary = lang.getPrimary();
+ return (primary.equalsIgnoreCase("ar") ||
+ primary.equalsIgnoreCase("fa") ||
+ primary.equalsIgnoreCase("ur") ||
+ primary.equalsIgnoreCase("ps") ||
+ primary.equalsIgnoreCase("syr") ||
+ primary.equalsIgnoreCase("dv") ||
+ primary.equalsIgnoreCase("he") ||
+ primary.equalsIgnoreCase("yi")) ? Direction.RTL : Direction.LTR;
+ }
+
+ /**
+ * Attempt to guess the base direction of an element using an analysis of
+ * the directional properties of the characters used. This is a brute-force
+ * style approach that can achieve fairly reasonable results when the element
+ * text consists primarily of characters with the same bidi properties. This
+ * approach is implemented by the Snarfer feed reader as is documented at
+ * http://www.xn--8ws00zhy3a.com/blog/2006/12/right-to-left-rss
+ *
+ * If the dir attribute is specified, the direction will be determine using it's value
+ * instead of the characteristics of the text
+ */
+ public static <T extends Element>Direction guessDirectionFromTextProperties(T element) {
+ return guessDirectionFromTextProperties(element, false);
+ }
+
+ /**
+ * Attempt to guess the base direction of an element using an analysis of
+ * the directional properties of the characters used. This is a brute-force
+ * style approach that can achieve fairly reasonable results when the element
+ * text consists primarily of characters with the same bidi properties. This
+ * approach is implemented by the Snarfer feed reader as is documented at
+ * http://www.xn--8ws00zhy3a.com/blog/2006/12/right-to-left-rss
+ *
+ * According to the Atom Bidi spec, if the dir attribute is set explicitly, we
+ * should not do language guessing. This restriction can be bypassed by setting
+ * ignoredir to true.
+ */
+ public static <T extends Element>Direction guessDirectionFromTextProperties(T element, boolean ignoredir) {
+ Direction dir = Direction.UNSPECIFIED;
+ if (!ignoredir && hasDirection(element)) return getDirection(element);
+ String text = element.getText();
+ if (text != null) {
+ int c = 0;
+ for (int n = 0; n < text.length(); n++) {
+ char ch = text.charAt(n);
+ if (Bidi.requiresBidi(new char[] {ch}, 0, 1)) c++;
+ else c--;
+ }
+ dir = (c > 0) ? Direction.RTL : Direction.LTR;
+ }
+ return dir;
+ }
+
+ /**
+ * Use Java's built in support for bidi text to determine the base directionality
+ * of the element's text. The response to this only indicates the *base* directionality,
+ * it does not indicate whether or not there are any RTL characters in the text.
+ *
+ * If the dir attribute is specified, the direction will be determine using it's value
+ * instead of the characteristics of the text
+ */
+ public static <T extends Element>Direction guessDirectionFromJavaBidi(T element) {
+ return guessDirectionFromJavaBidi(element, false);
+ }
+
+ /**
+ * Use Java's built in support for bidi text to determine the base directionality
+ * of the element's text. The response to this only indicates the *base* directionality,
+ * it does not indicate whether or not there are any RTL characters in the text.
+ *
+ * According to the Atom Bidi spec, if the dir attribute is set explicitly, we
+ * should not do language guessing. This restriction can be bypassed by setting
+ * ignoredir to true.
+ */
+ public static <T extends Element>Direction guessDirectionFromJavaBidi(T element, boolean ignoredir) {
+ Direction dir = Direction.UNSPECIFIED;
+ if (!ignoredir && hasDirection(element)) return getDirection(element);
+ String text = element.getText();
+ if (text != null) {
+ AttributedString s = new AttributedString(text);
+ Bidi bidi = new Bidi(s.getIterator());
+ dir = (bidi.baseIsLeftToRight()) ? Direction.LTR : Direction.RTL;
+ }
+ return dir;
+ }
+
+ private static <T extends Element>boolean hasDirection(T element) {
+ boolean answer = false;
+ String dir = element.getAttributeValue("dir");
+ if (dir != null && dir.length() > 0)
+ answer = true;
+ else if (dir == null) {
+ // if the direction is unspecified on this element,
+ // let's see if we've inherited it
+ Base parent = element.getParentElement();
+ if (parent != null &&
+ parent instanceof Element)
+ answer = hasDirection((Element)parent);
+ }
+ return answer;
+ }
+}
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/AbstractSelector.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/AbstractSelector.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/AbstractSelector.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/AbstractSelector.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,36 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.features;
+
+public abstract class AbstractSelector
+ implements Selector {
+
+ public Selector clone() {
+ try {
+ return (Selector) super.clone();
+ } catch (CloneNotSupportedException e) {
+ return copy();
+ }
+ }
+
+ protected Selector copy() {
+ throw new RuntimeException(
+ new CloneNotSupportedException());
+ }
+
+}
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/AcceptSelector.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/AcceptSelector.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/AcceptSelector.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/AcceptSelector.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,43 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.features;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.abdera.model.Collection;
+
+public class AcceptSelector
+ extends AbstractSelector
+ implements Selector {
+
+ private static final long serialVersionUID = -1289924342084041384L;
+ private final List<String> accepts = new ArrayList<String>();
+
+ public AcceptSelector(String... accepts) {
+ for (String accept : accepts) this.accepts.add(accept);
+ }
+
+ public boolean select(Collection collection) {
+ for (String accept : accepts) {
+ if (collection.accepts(accept)) return true;
+ }
+ return false;
+ }
+
+}
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/Feature.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/Feature.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/Feature.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/Feature.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,96 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.features;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ExtensibleElementWrapper;
+
+public class Feature
+ extends ExtensibleElementWrapper {
+
+ public enum Status {
+ UNSUPPORTED,
+ UNSPECIFIED,
+ SUPPORTED,
+ REQUIRED,
+ }
+
+ public Feature(Element internal) {
+ super(internal);
+ }
+
+ public Feature(Factory factory) {
+ super(factory, FeaturesHelper.FEATURE);
+ }
+
+ public IRI getRef() {
+ String ref = getAttributeValue("ref");
+ return (ref != null) ? new IRI(ref) : null;
+ }
+
+ public Status getStatus() {
+ String status = getAttributeValue("status");
+ return status != null ? Status.valueOf(status.toUpperCase()) : Status.SUPPORTED;
+ }
+
+ public void setStatus(Status status) {
+ if (status != null && status != Status.SUPPORTED) {
+ if (status != Status.UNSPECIFIED) {
+ setAttributeValue("status",status.name().toLowerCase());
+ } else {
+ throw new IllegalArgumentException(
+ "Cannot set the status to unspecified");
+ }
+ } else {
+ removeAttribute(new QName("status"));
+ }
+ }
+
+ public IRI getHref() {
+ String href = getAttributeValue("href");
+ return (href != null) ? new IRI(href) : null;
+ }
+
+ public String getLabel() {
+ return getAttributeValue("label");
+ }
+
+ public void setRef(String ref) {
+ if (ref == null) throw new IllegalArgumentException();
+ setAttributeValue("ref", (new IRI(ref)).toString());
+ }
+
+ public void setHref(String href) {
+ if (href != null)
+ setAttributeValue("href", (new IRI(href)).toString());
+ else
+ removeAttribute(new QName("href"));
+ }
+
+ public void setLabel(String label) {
+ if (label != null)
+ setAttributeValue("label", label);
+ else
+ removeAttribute(new QName("label"));
+ }
+
+}
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeatureSelector.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeatureSelector.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeatureSelector.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeatureSelector.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,84 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.features;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.abdera.ext.features.Feature.Status;
+import org.apache.abdera.model.Collection;
+
+public class FeatureSelector
+ extends AbstractSelector
+ implements Selector {
+
+ private static final long serialVersionUID = -8943638085557912175L;
+ private final Status minimumStatus;
+ private final List<String> features = new ArrayList<String>();
+
+ public FeatureSelector(String... features) {
+ this(Status.SUPPORTED,features);
+ }
+
+ public FeatureSelector(Status minimumStatus, String... features) {
+ this.minimumStatus = minimumStatus;
+ for (String feature : features) this.features.add(feature);
+ }
+
+ public boolean select(Collection collection) {
+ for (String feature : features) {
+ Status status = FeaturesHelper.getFeatureStatus(collection, feature);
+ if (status != null && status.ordinal() >= minimumStatus.ordinal())
+ return true;
+ }
+ return false;
+ }
+
+ public String[] getFeatures() {
+ return features.toArray(new String[features.size()]);
+ }
+
+ public Status getMinimumStatus() {
+ return minimumStatus;
+ }
+
+ @Override
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((features == null) ? 0 : features.hashCode());
+ result = PRIME * result + ((minimumStatus == null) ? 0 : minimumStatus.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ final FeatureSelector other = (FeatureSelector) obj;
+ if (features == null) {
+ if (other.features != null) return false;
+ } else if (!features.equals(other.features)) return false;
+ if (minimumStatus == null) {
+ if (other.minimumStatus != null) return false;
+ } else if (!minimumStatus.equals(other.minimumStatus)) return false;
+ return true;
+ }
+
+}
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeaturesExtensionFactory.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeaturesExtensionFactory.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeaturesExtensionFactory.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeaturesExtensionFactory.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,30 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.features;
+
+import org.apache.abdera.util.AbstractExtensionFactory;
+
+public final class FeaturesExtensionFactory
+ extends AbstractExtensionFactory {
+
+ public FeaturesExtensionFactory() {
+ super(FeaturesHelper.FNS);
+ addImpl(FeaturesHelper.FEATURE,Feature.class);
+ }
+
+}
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeaturesHelper.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeaturesHelper.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeaturesHelper.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/FeaturesHelper.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,352 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.features;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.activation.MimeType;
+import javax.activation.MimeTypeParseException;
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.ext.features.Feature.Status;
+import org.apache.abdera.ext.thread.ThreadConstants;
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.model.Collection;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.Service;
+import org.apache.abdera.model.Workspace;
+import org.apache.abdera.util.MimeTypeHelper;
+
+/**
+ * Implementation of the current APP Features Draft
+ * (http://www.ietf.org/internet-drafts/draft-snell-atompub-feature-05.txt)
+ */
+public final class FeaturesHelper {
+
+ public static final String FNS = "http://purl.org/atompub/features/1.0";
+ public static final QName FEATURE = new QName(FNS, "feature","f");
+ public static final QName TYPE = new QName(FNS, "type", "f");
+
+ private static final String FEATURE_BASE = "http://www.w3.org/2007/app/";
+ public static final String FEATURE_DRAFTS = FEATURE_BASE + "drafts";
+ public static final String FEATURE_XHTML_CONTENT = FEATURE_BASE + "xhtml-content";
+ public static final String FEATURE_HTML_CONTENT = FEATURE_BASE + "html-content";
+ public static final String FEATURE_TEXT_CONTENT = FEATURE_BASE + "text-content";
+ public static final String FEATURE_XML_CONTENT = FEATURE_BASE + "xml-content";
+ public static final String FEATURE_BINARY_CONTENT = FEATURE_BASE + "binary-content";
+ public static final String FEATURE_REF_CONTENT = FEATURE_BASE + "ref-content";
+ public static final String FEATURE_XHTML_TITLE = FEATURE_BASE + "xhtml-title";
+ public static final String FEATURE_HTML_TITLE = FEATURE_BASE + "html-title";
+ public static final String FEATURE_TEXT_TITLE = FEATURE_BASE + "text-title";
+ public static final String FEATURE_XHTML_SUMMARY = FEATURE_BASE + "xhtml-summary";
+ public static final String FEATURE_HTML_SUMMARY = FEATURE_BASE + "html-summary";
+ public static final String FEATURE_TEXT_SUMMARY = FEATURE_BASE + "text-summary";
+ public static final String FEATURE_AUTO_SUMMARY = FEATURE_BASE + "auto-summary";
+ public static final String FEATURE_XHTML_RIGHTS = FEATURE_BASE + "xhtml-rights";
+ public static final String FEATURE_HTML_RIGHTS = FEATURE_BASE + "html-rights";
+ public static final String FEATURE_TEXT_RIGHTS = FEATURE_BASE + "text-rights";
+ public static final String FEATURE_AUTH_AUTHOR = FEATURE_BASE + "auth-author";
+ public static final String FEATURE_SLUG = FEATURE_BASE + "slug";
+ public static final String FEATURE_MULTIPLE_CATEGORIES = FEATURE_BASE + "multiple-categories";
+ public static final String FEATURE_MULTIPLE_AUTHORS = FEATURE_BASE + "multiple-authors";
+ public static final String FEATURE_MULTIPLE_CONTRIBUTORS = FEATURE_BASE + "multiple-contributors";
+ public static final String FEATURE_PRESERVE_INFOSET = FEATURE_BASE + "preserve-infoset";
+ public static final String FEATURE_PRESERVE_ID = FEATURE_BASE + "preserve-id";
+ public static final String FEATURE_PRESERVE_DATES = FEATURE_BASE + "preserve-dates";
+ public static final String FEATURE_PRESERVE_EXTENSIONS = FEATURE_BASE + "preserve-extensions";
+ public static final String FEATURE_PRESERVE_LINKS = FEATURE_BASE + "preserve-links";
+ public static final String FEATURE_PRESERVE_RIGHTS = FEATURE_BASE + "preserve-rights";
+ public static final String FEATURE_SCHEDULED_PUBLISHING = FEATURE_BASE + "scheduled-publishing";
+ public static final String FEATURE_THREADING = ThreadConstants.THR_NS;
+
+
+ private static final String ABDERA_FEATURE_BASE = "http://incubator.apache.org/abdera/features/";
+
+ /**
+ * Indicates that the collection will accept digitally signed entries
+ * If marked as "required", the collection will only accept digitally signed entries
+ */
+ public static final String ABDERA_FEATURE_SIGNATURE = ABDERA_FEATURE_BASE + "signature";
+
+ /**
+ * Indicates that the collection will preserve XML digital signatures contained
+ * in member resources
+ */
+ public static final String ABDERA_FEATURE_PRESERVE_SIGNATURE = ABDERA_FEATURE_BASE + "preserve-signature";
+
+ /**
+ * Indicates that the collection supports the use of the Atom Bidi Attribute.
+ * If marked as "required", the collection will only accept entries that contain the bidi attribute
+ */
+ public static final String ABDERA_FEATURE_BIDI = ABDERA_FEATURE_BASE + "bidi";
+
+ /**
+ * Indicates that the collection supports the use of Diffie-Hellman key exchange
+ * for XML encrypted requests
+ */
+ public static final String ABDERA_FEATURE_DHENCREQUEST = ABDERA_FEATURE_BASE + "dhenc-request";
+
+ /**
+ * Indicates that the collection supports the use of Diffie-Hellman key exchange
+ * for XML encrypted responses
+ */
+ public static final String ABDERA_FEATURE_DHENCRESPONSE = ABDERA_FEATURE_BASE + "dhenc-response";
+
+ /**
+ * Indicates that the collection will add it's own digital signature to the
+ * collection feed and member resources
+ */
+ public static final String ABDERA_FEATURE_SIGNED_RESPONSE = ABDERA_FEATURE_BASE + "response-signature";
+
+ /**
+ * Indicates that the collection supports the use of Geo extensions (see the
+ * org.apache.abdera.ext.geo Package)
+ */
+ public static final String ABDERA_FEATURE_GEO = ABDERA_FEATURE_BASE + "geo";
+
+ /**
+ * Indicates that the collection supports the use of the Feed paging standard.
+ * (ftp://ftp.rfc-editor.org/in-notes/internet-drafts/draft-nottingham-atompub-feed-history-11.txt)
+ * See the org.apache.abdera.ext.history Package)
+ */
+ public static final String ABDERA_FEATURE_PAGING = ABDERA_FEATURE_BASE + "paging";
+
+ /**
+ * Indicates that the collection supports the use of the Simple Sharing Extensions
+ * (see the org.apache.abdera.ext.sharing Package)
+ */
+ public static final String ABDERA_FEATURE_SHARING = ABDERA_FEATURE_BASE + "sharing";
+
+ /**
+ * Indicates that the collection supports the GoogleLogin auth scheme
+ * (see the org.apache.abdera.ext.gdata Package)
+ */
+ public static final String ABDERA_FEATURE_GOOGLELOGIN = ABDERA_FEATURE_BASE + "googlelogin";
+
+ /**
+ * Indicates that the collection supports the WSSE auth scheme
+ * (see the org.apache.abdera.ext.wsse Package)
+ */
+ public static final String ABDERA_FEATURE_WSSE = ABDERA_FEATURE_BASE + "wsse";
+
+
+
+
+ private FeaturesHelper() {}
+
+ /**
+ * Returns the specified feature element or null
+ */
+ public static Feature getFeature(
+ Collection collection,
+ String feature) {
+ List<Element> list = collection.getExtensions(FEATURE);
+ for (Element el : list) {
+ if (el.getAttributeValue("ref").equals(feature))
+ return (Feature) el;
+ }
+ return null;
+ }
+
+ public static Status getFeatureStatus(Collection collection, String feature) {
+ Feature f = getFeature(collection,feature);
+ return f != null ? f.getStatus() : Status.UNSPECIFIED;
+ }
+
+ public static Feature[] getSupportedFeatures(Collection collection) {
+ return getFeatures(collection, Status.SUPPORTED);
+ }
+
+ public static Feature[] getUnsupportedFeatures(Collection collection) {
+ return getFeatures(collection, Status.UNSUPPORTED);
+ }
+
+ public static Feature[] getRequiredFeatures(Collection collection) {
+ return getFeatures(collection, Status.REQUIRED);
+ }
+
+ public static Feature[] getFeatures(Collection collection, Status status) {
+ if (status == null) status = Status.SUPPORTED;
+ List<Feature> list = new ArrayList<Feature>();
+ List<Feature> features = collection.getExtensions(FEATURE);
+ for (Feature feature : features) {
+ if (status == feature.getStatus()) {
+ list.add(feature);
+ }
+ }
+ return list.toArray(new Feature[list.size()]);
+ }
+
+ /**
+ * Add the specified features to the collection
+ */
+ public static Feature[] addFeatures(
+ Collection collection,
+ String... features) {
+ List<Feature> list = new ArrayList<Feature>();
+ for (String feature : features)
+ list.add(addFeature(collection,feature));
+ return list.toArray(new Feature[list.size()]);
+ }
+
+ /**
+ * Add the specified features to the collection
+ */
+ public static Feature[] addFeatures(
+ Collection collection,
+ Status status,
+ String... features) {
+ List<Feature> list = new ArrayList<Feature>();
+ for (String feature : features)
+ list.add(addFeature(collection,feature, status));
+ return list.toArray(new Feature[list.size()]);
+ }
+
+ /**
+ * Add the specified feature to the collection
+ * @param collection The collection
+ * @param feature The IRI of the feature to add
+ */
+ public static Feature addFeature(
+ Collection collection,
+ String feature) {
+ return addFeature(
+ collection,
+ feature,
+ null, null, null);
+ }
+
+ /**
+ * Add the specified feature to the collection
+ * @param collection The collection
+ * @param feature The IRI of the feature to add
+ */
+ public static Feature addFeature(
+ Collection collection,
+ String feature,
+ Status status) {
+ return addFeature(
+ collection,
+ feature,
+ status,
+ null, null);
+ }
+
+ /**
+ * Add the specified feature to the collection
+ * @param collection The collection
+ * @param feature The IRI of the feature to add
+ * @param required True if the feature is required
+ * @param href An IRI pointing to a human readable resource describing the feature
+ * @param label A human readable label for the feature
+ */
+ public static Feature addFeature(
+ Collection collection,
+ String feature,
+ Status status,
+ String href,
+ String label) {
+ if (getFeature(collection, feature) != null)
+ throw new IllegalArgumentException("Feature already specified");
+ Factory factory = collection.getFactory();
+ Feature el =
+ (Feature)factory.newExtensionElement(
+ FeaturesHelper.FEATURE, collection);
+ collection.declareNS(FNS, "f");
+ el.setRef(new IRI(feature).toString());
+ el.setStatus(status);
+ if (href != null) el.setHref(new IRI(href).toString());
+ if (label != null) el.setLabel(label);
+ return el;
+ }
+
+ /**
+ * Select a Collection from the service document
+ */
+ public static Collection[] select(Service service, Selector selector) {
+ return select(service, new Selector[] {selector});
+ }
+
+ /**
+ * Select a Collection from the service document
+ */
+ public static Collection[] select(Service service, Selector... selectors) {
+ List<Collection> list = new ArrayList<Collection>();
+ for (Workspace workspace : service.getWorkspaces()) {
+ Collection[] collections = select(workspace, selectors);
+ for (Collection collection : collections)
+ list.add(collection);
+ }
+ return list.toArray(new Collection[list.size()]);
+ }
+
+ /**
+ * Select a Collection from the Workspace
+ */
+ public static Collection[] select(Workspace workspace, Selector selector) {
+ return select(workspace, new Selector[] {selector});
+ }
+
+ /**
+ * Select a Collection from the Workspace
+ */
+ public static Collection[] select(Workspace workspace, Selector... selectors) {
+ List<Collection> list = new ArrayList<Collection>();
+ for (Collection collection : workspace.getCollections()) {
+ boolean accept = true;
+ for (Selector selector : selectors) {
+ if (!selector.select(collection)) {
+ accept = false;
+ break;
+ }
+ }
+ if (accept) list.add(collection);
+ }
+ return list.toArray(new Collection[list.size()]);
+ }
+
+ public static void addType(Feature feature, String mediaRange) {
+ addType(feature, new String[] {mediaRange});
+ }
+
+ public static void addType(Feature feature, String... mediaRanges) {
+ mediaRanges = MimeTypeHelper.condense(mediaRanges);
+ for (String mediaRange : mediaRanges) {
+ try {
+ feature.addSimpleExtension(TYPE, new MimeType(mediaRange).toString());
+ } catch (MimeTypeParseException e) {}
+ }
+ }
+
+ public static String[] getTypes(Feature feature) {
+ List<String> list = new ArrayList<String>();
+ for (Element type : feature.getExtensions(TYPE)) {
+ String value = type.getText();
+ if (value != null) {
+ value = value.trim();
+ try {
+ list.add(new MimeType(value).toString());
+ } catch (MimeTypeParseException e) {}
+ }
+ }
+ return list.toArray(new String[list.size()]);
+ }
+
+}
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/Selector.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/Selector.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/Selector.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/Selector.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,31 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.features;
+
+import java.io.Serializable;
+
+import org.apache.abdera.model.Collection;
+
+public interface Selector
+ extends Cloneable, Serializable {
+
+ boolean select(Collection collection);
+
+ Selector clone();
+
+}
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/XPathSelector.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/XPathSelector.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/XPathSelector.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/features/XPathSelector.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,89 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.features;
+
+import java.util.Map;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.model.Collection;
+import org.apache.abdera.xpath.XPath;
+
+/**
+ * Selects a collection based on a boolean XPath expression
+ */
+public class XPathSelector
+ extends AbstractSelector
+ implements Selector {
+
+ private static final long serialVersionUID = 7751803876821166591L;
+
+ private final XPath xpath;
+ private final Map<String,String> namespaces;
+ private final String path;
+
+ public XPathSelector(
+ String path) {
+ this(path,(new Abdera()).getXPath());
+ }
+
+ public XPathSelector(
+ String path,
+ XPath xpath) {
+ this(path,xpath,xpath.getDefaultNamespaces());
+ }
+
+ public XPathSelector(
+ String path,
+ XPath xpath,
+ Map<String,String> namespaces) {
+ this.path = path;
+ this.xpath = xpath;
+ this.namespaces = namespaces;
+ if (!this.namespaces.containsValue(FeaturesHelper.FNS)) {
+ int c = 0;
+ String p = "f";
+ if (!this.namespaces.containsKey(p)) {
+ this.namespaces.put(p, FeaturesHelper.FNS);
+ } else {
+ String s = p + c;
+ while (this.namespaces.containsKey(s)) {
+ c++; s = p + c;
+ }
+ this.namespaces.put(s, FeaturesHelper.FNS);
+ }
+ }
+ }
+
+ public String getFeaturesPrefix() {
+ for (Map.Entry<String,String> entry : namespaces.entrySet()) {
+ if (entry.getValue().equals(FeaturesHelper.FNS)) return entry.getKey();
+ }
+ return null;
+ }
+
+ public boolean select(Collection collection) {
+ if (xpath.booleanValueOf(path, collection, namespaces)) {
+ return true;
+ }
+ return false;
+ }
+
+ public void addNamespace(String prefix, String uri) {
+ namespaces.put(prefix, uri);
+ }
+}
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/history/FeedPagingHelper.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/history/FeedPagingHelper.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/history/FeedPagingHelper.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/history/FeedPagingHelper.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,289 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.history;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.Feed;
+import org.apache.abdera.model.Link;
+import org.apache.abdera.i18n.iri.IRI;
+
+/**
+ * Initial support for Mark Nottingham's Feed Paging and Archiving draft
+ * (http://ietfreport.isoc.org/all-ids/draft-nottingham-atompub-feed-history-11.txt)
+ */
+public final class FeedPagingHelper {
+
+ public static final String FH_PREFIX = "fh";
+ public static final String FHNS = "http://purl.org/syndication/history/1.0";
+ public static final QName COMPLETE = new QName(FHNS, "complete", FH_PREFIX);
+ public static final QName ARCHIVE = new QName(FHNS, "archive", FH_PREFIX);
+
+ FeedPagingHelper() {}
+
+ /**
+ * Returns true if the feed is "complete". According to the Feed Paging
+ * and Archiving specification, in a complete feed, "any entry not actually
+ * in the feed document SHOULD NOT be considered to be part of that feed."
+ * @param feed The feed to check
+ */
+ public static boolean isComplete(Feed feed) {
+ return (feed.getExtension(COMPLETE) != null);
+ }
+
+ /**
+ * Flag the feed as being complete. According to the Feed Paging
+ * and Archiving specification, in a complete feed, "any entry not actually
+ * in the feed document SHOULD NOT be considered to be part of that feed."
+ * @param feed The Feed to mark as complete
+ * @param complete True if the feed is complete
+ */
+ public static void setComplete(Feed feed, boolean complete) {
+ if (complete) {
+ if (!isComplete(feed)) feed.addExtension(COMPLETE);
+ } else {
+ if (isComplete(feed)) {
+ Element ext = feed.getExtension(COMPLETE);
+ ext.discard();
+ }
+ }
+ }
+
+ /**
+ * Flag the feed as being an archive.
+ * @param feed The Feed to mark as an archive
+ * @param archive True if the feed is an archive
+ */
+ public static void setArchive(Feed feed, boolean archive) {
+ if (archive) {
+ if (!isArchive(feed)) feed.addExtension(ARCHIVE);
+ } else {
+ if (isArchive(feed)) {
+ Element ext = feed.getExtension(ARCHIVE);
+ ext.discard();
+ }
+ }
+ }
+
+ /**
+ * Return true if the feed has been marked as an archive
+ * @param feed The feed to check
+ */
+ public static boolean isArchive(Feed feed) {
+ return feed.getExtension(ARCHIVE) != null;
+ }
+
+ /**
+ * Return true if the feed contains any next, previous, first or last
+ * paging link relations
+ * @param feed The feed to check
+ */
+ public static boolean isPaged(Feed feed) {
+ return feed.getLink("next") != null ||
+ feed.getLink("previous") != null ||
+ feed.getLink("first") != null ||
+ feed.getLink("last") != null;
+ }
+
+ /**
+ * Adds a next link relation to the feed
+ * @param feed The feed
+ * @param iri The IRI of the next feed document
+ * @return The newly created Link
+ */
+ public static Link setNext(Feed feed, String iri) {
+ Link link = feed.getLink("next");
+ if (link != null) {
+ link.setHref(iri);
+ } else {
+ link = feed.addLink(iri, "next");
+ }
+ return link;
+ }
+
+ /**
+ * Adds a previous link relation to the feed
+ * @param feed The feed
+ * @param iri The IRI of the previous feed document
+ * @return The newly created Link
+ */
+ public static Link setPrevious(Feed feed, String iri) {
+ Link link = feed.getLink("previous");
+ if (link != null) {
+ link.setHref(iri);
+ } else {
+ link = feed.addLink(iri, "previous");
+ }
+ return link;
+ }
+
+ /**
+ * Adds a first link relation to the feed
+ * @param feed The feed
+ * @param iri The IRI of the first feed document
+ * @return The newly created Link
+ */
+ public static Link setFirst(Feed feed, String iri) {
+ Link link = feed.getLink("first");
+ if (link != null) {
+ link.setHref(iri);
+ } else {
+ link = feed.addLink(iri, "first");
+ }
+ return link;
+ }
+
+ /**
+ * Adds a last link relation to the feed
+ * @param feed The feed
+ * @param iri The IRI of the last feed document
+ * @return The newly created Link
+ */
+ public static Link setLast(Feed feed, String iri) {
+ Link link = feed.getLink("last");
+ if (link != null) {
+ link.setHref(iri);
+ } else {
+ link = feed.addLink(iri, "last");
+ }
+ return link;
+ }
+
+ /**
+ * Adds a next-archive link relation to the feed
+ * @param feed The feed
+ * @param iri The IRI of the next archive feed document
+ * @return The newly created Link
+ */
+ public static Link setNextArchive(Feed feed, String iri) {
+ Link link = feed.getLink("next-archive");
+ if (link == null) { // try the full IANA URI version
+ link = feed.getLink(Link.IANA_BASE + "next-archive");
+ }
+ if (link != null) {
+ link.setHref(iri);
+ } else {
+ link = feed.addLink(iri, "next-archive");
+ }
+ return link;
+ }
+
+ /**
+ * Adds a prev-archive link relation to the feed
+ * @param feed The feed
+ * @param iri The IRI of the previous archive feed document
+ * @return The newly created Link
+ */
+ public static Link setPreviousArchive(Feed feed, String iri) {
+ Link link = feed.getLink("prev-archive");
+ if (link == null) { // try the full IANA URI version
+ link = feed.getLink(Link.IANA_BASE + "prev-archive");
+ }
+ if (link != null) {
+ link.setHref(iri);
+ } else {
+ link = feed.addLink(iri, "prev-archive");
+ }
+ return link;
+ }
+
+ /**
+ * Adds a current link relation to the feed
+ * @param feed The feed
+ * @param iri The IRI of the current feed document
+ * @return The newly created Link
+ */
+ public static Link setCurrent(Feed feed, String iri) {
+ Link link = feed.getLink("current");
+ if (link == null) { // try the full IANA URI version
+ link = feed.getLink(Link.IANA_BASE + "current");
+ }
+ if (link != null) {
+ link.setHref(iri);
+ } else {
+ link = feed.addLink(iri, "current");
+ }
+ return link;
+ }
+
+ /**
+ * Returns the IRI of the next link relation
+ */
+ public static IRI getNext(Feed feed) {
+ Link link = feed.getLink("next");
+ return (link != null) ? link.getResolvedHref() : null;
+ }
+
+ /**
+ * Returns the IRI of the previous link relation
+ */
+ public static IRI getPrevious(Feed feed) {
+ Link link = feed.getLink("previous");
+ return (link != null) ? link.getResolvedHref() : null;
+ }
+
+ /**
+ * Returns the IRI of the first link relation
+ */
+ public static IRI getFirst(Feed feed) {
+ Link link = feed.getLink("first");
+ return (link != null) ? link.getResolvedHref() : null;
+ }
+
+ /**
+ * Returns the IRI of the last link relation
+ */
+ public static IRI getLast(Feed feed) {
+ Link link = feed.getLink("last");
+ return (link != null) ? link.getResolvedHref() : null;
+ }
+
+ /**
+ * Returns the IRI of the prev-archive link relation
+ */
+ public static IRI getPreviousArchive(Feed feed) {
+ Link link = feed.getLink("prev-archive");
+ if (link == null) { // try the full IANA URI version
+ link = feed.getLink(Link.IANA_BASE + "prev-archive");
+ }
+ return (link != null) ? link.getResolvedHref() : null;
+ }
+
+ /**
+ * Returns the IRI of the next-archive link relation
+ */
+ public static IRI getNextArchive(Feed feed) {
+ Link link = feed.getLink("next-archive");
+ if (link == null) { // try the full IANA URI version
+ link = feed.getLink(Link.IANA_BASE + "next-archive");
+ }
+ return (link != null) ? link.getResolvedHref() : null;
+ }
+
+ /**
+ * Returns the IRI of the current link relation
+ */
+ public static IRI getCurrent(Feed feed) {
+ Link link = feed.getLink("current");
+ if (link == null) { // try the full IANA URI version
+ link = feed.getLink(Link.IANA_BASE + "current");
+ }
+ return (link != null) ? link.getResolvedHref() : null;
+ }
+}
Added: incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/license/LicenseHelper.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/license/LicenseHelper.java?rev=567888&view=auto
==============================================================================
--- incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/license/LicenseHelper.java (added)
+++ incubator/abdera/java/trunk/extensions/main/src/main/java/org/apache/abdera/ext/license/LicenseHelper.java Mon Aug 20 17:51:20 2007
@@ -0,0 +1,150 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. 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. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.license;
+
+import java.util.List;
+
+import org.apache.abdera.i18n.iri.IRI;
+import org.apache.abdera.model.Base;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Link;
+import org.apache.abdera.model.Source;
+
+/**
+ * Implementation of the Atom License Extension, RFC 4946
+ */
+public final class LicenseHelper {
+
+ public static final String UNSPECIFIED_LICENSE = "http://purl.org/atompub/license#unspecified";
+
+ LicenseHelper() {}
+
+ public static List<Link> getLicense(
+ Base base,
+ boolean inherited) {
+ List<Link> links = null;
+ if (base instanceof Source) {
+ links = ((Source)base).getLinks(Link.REL_LICENSE);
+ } else if (base instanceof Entry) {
+ Entry entry = (Entry)base;
+ Source source = entry.getSource();
+ Base parent = entry.getParentElement();
+ links = entry.getLinks(Link.REL_LICENSE);
+ if (inherited && (links == null || links.size() == 0) && source != null) {
+ links = getLicense(source, false);
+ }
+ if (inherited && (links == null || links.size() == 0) && parent != null) {
+ links = getLicense(parent, false);
+ }
+ }
+ return links;
+ }
+
+ public static List<Link> getLicense(
+ Base base) {
+ return getLicense(base, true);
+ }
+
+ public static boolean hasUnspecifiedLicense(
+ Base base,
+ boolean inherited) {
+ return hasLicense(base, UNSPECIFIED_LICENSE, inherited);
+ }
+
+ public static boolean hasUnspecifiedLicense(
+ Base base) {
+ return hasUnspecifiedLicense(base, true);
+ }
+
+ public static boolean hasLicense(
+ Base base,
+ String iri,
+ boolean inherited) {
+ List<Link> links = getLicense(base, inherited);
+ IRI check = new IRI(iri);
+ boolean answer = false;
+ if (links != null) {
+ for (Link link : links) {
+ if (link.getResolvedHref().equals(check)) {
+ answer = true;
+ break;
+ }
+ }
+ }
+ return answer;
+ }
+
+ public static boolean hasLicense(
+ Base base,
+ String iri) {
+ return hasLicense(base, iri, true);
+ }
+
+ public static boolean hasLicense(
+ Base base,
+ boolean inherited) {
+ List<Link> links = getLicense(base, inherited);
+ return (links != null && links.size() > 0);
+ }
+
+ public static boolean hasLicense(
+ Base base) {
+ return hasLicense(base, true);
+ }
+
+ public static Link addUnspecifiedLicense(
+ Base base) {
+ if (hasUnspecifiedLicense(base,false))
+ throw new IllegalStateException("Unspecified license already added");
+ if (hasLicense(base,false))
+ throw new IllegalStateException("Other licenses are already added.");
+ return addLicense(base, UNSPECIFIED_LICENSE);
+ }
+
+ public static Link addLicense(
+ Base base,
+ String iri) {
+ return addLicense(base, iri, null, null, null);
+ }
+
+ public static Link addLicense(
+ Base base,
+ String iri,
+ String title) {
+ return addLicense(base, iri, null, title, null);
+ }
+
+ public static Link addLicense(
+ Base base,
+ String iri,
+ String type,
+ String title,
+ String hreflang) {
+ if (hasLicense(base, iri,false))
+ throw new IllegalStateException("License '" + iri + "' has already been added");
+ if (hasUnspecifiedLicense(base,false))
+ throw new IllegalStateException("Unspecified license already added");
+ if (base instanceof Source) {
+ return ((Source)base).addLink((new IRI(iri)).toString(), Link.REL_LICENSE, type, title, hreflang, -1);
+ } else if (base instanceof Entry) {
+ return ((Entry)base).addLink((new IRI(iri)).toString(), Link.REL_LICENSE, type, title, hreflang, -1);
+ }
+ return null;
+ }
+
+}