You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by su...@apache.org on 2011/08/25 17:03:28 UTC

svn commit: r1161593 [1/2] - in /incubator/stanbol/trunk/cmsadapter: core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/ core/src/main/resources/OSGI-INF/metatype/ servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/ s...

Author: suat
Date: Thu Aug 25 15:03:28 2011
New Revision: 1161593

URL: http://svn.apache.org/viewvc?rev=1161593&view=rev
Log:
STANBOL 306:
servicesapi:
-Added methods to RDFBridge and RDFMapper interfaces to be used while generating RDF from content repository
core:
-Removed the DefaultRDFBridgeConfiguration interface and its implementation instead the default configurations are given directly in the default implementation of RDFBridge
-Copied NamespaceEnum from the Entityhub to break the dependency. As a TODO, that NamespaceEnum can be moved in a common directory that can be used by several components of Stanbol

Added:
    incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/BaseRDFMapper.java
    incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/DefaultRDFBridgeImpl.java
      - copied, changed from r1157077, incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/DefaultRDFBridgeImpl.java
    incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/NamespaceEnum.java
Removed:
    incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/DefaultRDFBridgeConfigurationImpl.java
    incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/mapping/RDFBridgeConfiguration.java
Modified:
    incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/RDFBridgeHelper.java
    incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/RDFBridgeManager.java
    incubator/stanbol/trunk/cmsadapter/core/src/main/resources/OSGI-INF/metatype/metatype.properties
    incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/CMSAdapterVocabulary.java
    incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/mapping/RDFBridge.java
    incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/mapping/RDFMapper.java

Added: incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/BaseRDFMapper.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/BaseRDFMapper.java?rev=1161593&view=auto
==============================================================================
--- incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/BaseRDFMapper.java (added)
+++ incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/BaseRDFMapper.java Thu Aug 25 15:03:28 2011
@@ -0,0 +1,59 @@
+package org.apache.stanbol.cmsadapter.core.mapping;
+
+import org.apache.clerezza.rdf.core.MGraph;
+import org.apache.clerezza.rdf.core.NonLiteral;
+import org.apache.stanbol.cmsadapter.servicesapi.helper.CMSAdapterVocabulary;
+import org.apache.stanbol.cmsadapter.servicesapi.mapping.RDFMapper;
+
+/**
+ * This class contains common methods to be used in {@link RDFMapper} implementations
+ * 
+ * @author suat
+ * 
+ */
+public class BaseRDFMapper {
+    /**
+     * Obtains the name for the CMS object based on the RDF data provided. If
+     * {@link CMSAdapterVocabulary#CMS_OBJECT_NAME} assertion is already provided, its value is returned;
+     * otherwise the local name is extracted from the URI given.
+     * 
+     * @param subject
+     *            {@link NonLiteral} representing the URI of the CMS object resource
+     * @param graph
+     *            {@link MGraph} holding the resources
+     * @return the name for the CMS object to be created/updated in the repository
+     */
+    protected String getObjectName(NonLiteral subject, MGraph graph) {
+        String objectName = RDFBridgeHelper.getResourceStringValue(subject,
+            CMSAdapterVocabulary.CMS_OBJECT_NAME, graph);
+        if (objectName.contentEquals("")) {
+            return RDFBridgeHelper.extractLocalNameFromURI(subject);
+        } else {
+            return objectName;
+        }
+    }
+
+    /**
+     * Obtains the path for the CMS object based on the name of the object and RDF provided. If
+     * {@link CMSAdapterVocabulary#CMS_OBJECT_PATH} assertion is already provided, its value is returned;
+     * otherwise its name is returned together with a preceding "/" character. This means CMS object will be
+     * searched under the root path
+     * 
+     * @param subject
+     *            {@link NonLiteral} representing the URI of the CMS object resource
+     * @param name
+     *            name of the CMS object to be created in the repository
+     * @param graph
+     *            {@link MGraph} holding the resource
+     * @return the path for the CMS object to be created/updated in the repository
+     */
+    protected String getObjectPath(NonLiteral subject, String name, MGraph graph) {
+        String objectPath = RDFBridgeHelper.getResourceStringValue(subject,
+            CMSAdapterVocabulary.CMS_OBJECT_PATH, graph);
+        if (objectPath.contentEquals("")) {
+            return "/" + name;
+        } else {
+            return objectPath;
+        }
+    }
+}

Copied: incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/DefaultRDFBridgeImpl.java (from r1157077, incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/DefaultRDFBridgeImpl.java)
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/DefaultRDFBridgeImpl.java?p2=incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/DefaultRDFBridgeImpl.java&p1=incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/DefaultRDFBridgeImpl.java&r1=1157077&r2=1161593&rev=1161593&view=diff
==============================================================================
--- incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/DefaultRDFBridgeImpl.java (original)
+++ incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/DefaultRDFBridgeImpl.java Thu Aug 25 15:03:28 2011
@@ -16,117 +16,148 @@
  */
 package org.apache.stanbol.cmsadapter.core.mapping;
 
+import java.util.ArrayList;
+import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.apache.clerezza.rdf.core.Graph;
 import org.apache.clerezza.rdf.core.LiteralFactory;
 import org.apache.clerezza.rdf.core.MGraph;
 import org.apache.clerezza.rdf.core.NonLiteral;
+import org.apache.clerezza.rdf.core.Resource;
 import org.apache.clerezza.rdf.core.Triple;
 import org.apache.clerezza.rdf.core.UriRef;
 import org.apache.clerezza.rdf.core.impl.SimpleMGraph;
 import org.apache.clerezza.rdf.core.impl.TripleImpl;
+import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
-import org.apache.felix.scr.annotations.ReferenceStrategy;
+import org.apache.felix.scr.annotations.Properties;
+import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.stanbol.cmsadapter.servicesapi.helper.CMSAdapterVocabulary;
+import org.apache.stanbol.cmsadapter.servicesapi.helper.NamespaceEnum;
 import org.apache.stanbol.cmsadapter.servicesapi.mapping.RDFBridge;
-import org.apache.stanbol.cmsadapter.servicesapi.mapping.RDFBridgeConfiguration;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Default implementation of {@link RDFBridge} interface. It basically provides annotation of raw RDF data
- * using the {@link RDFBridgeConfiguration} instances available in the environment.
+ * Default implementation of {@link RDFBridge} interface. It provides annotation of raw RDF data and
+ * generating RDF from the content repository based on the configurations described below:
+ * 
+ * <ul>
+ * <li><b>Resource selector:</b></li> This property is used to filter resources from the RDF data. It should
+ * have the syntax:<br>
+ * <b> rdf:Type > skos:Concept </b>. This example states that triples having value <b>skos:Concept</b> of
+ * <b>rdf:type</b> predicate will be filtered. And subject of selected triples indicates the resource to be
+ * created/updated as node/object in the repository. It is also acceptable to pass full URIs such as <br>
+ * <b> http://www.w3.org/1999/02/22-rdf-syntax-ns#type > http://www.w3.org/2004/02/skos/core#Concept</b><br>
+ * <li><b>Name:</b></li> This configuration indicates the predicate which points to the name of node/object to
+ * be created in the repository. It should indicate a single URI such as <b>rdfs:label</b> or
+ * <b>http://www.w3.org/2000/01/rdf-schema#label</b>. Actually name value is obtained through the triple
+ * (s,p,o) where <b>s</b> is one of the subjects filtered by the "Resource Selector" configuration, <b>p</b>
+ * is this parameter. This configuration is optional. If an empty configuration is passed name of the CMS
+ * objects will be set as the local name of the URI represented by <b>s</b><br>
+ * <li><b>Children:</b></li> This property specifies the children of nodes/objects to be created in the
+ * repository. Value of this configuration should be like <b>skos:narrower > narrowerObject</b> or
+ * <b>skos:narrower > rdfs:label</b>. First option has same logic with the previous parameter. It determines
+ * the name of the child CMS object to be created/updated. In the second case, value rdfs:label predicate of
+ * resource representing child object will be set as the name of child object/node in the repository. This
+ * option would be useful to create hierarchies.
+ * <p>
+ * It is also possible to set only predicate indicating the subsumption relations such as only
+ * <b>skos:narrower</b>. In this case name of the child resource will be obtained from the local name of URI
+ * representing this CMS object. This configuration is optional.
+ * <li><b>Default child predicate:</b></li> First of all this configuration is used only when generating an
+ * RDF from the repository. If there are more than one child selector in previous configuration, it is not
+ * possible to detect the predicate that will be used as the child assertion. In that case, this configuration
+ * is used to set child assertion between parent and child objects. This configuration is optional. But if
+ * there is a case in which this configuration should be used and if it is not set, this causes missing
+ * assertions in the generated RDF.
+ * <li><b>Content repository path:</b></li> This property specifies the content repository path in which the
+ * new CMS objects will be created or existing ones will be updated.
+ * </ul>
  * 
  * @author suat
  * 
  */
-@Component(immediate = true)
+@Component(configurationFactory = true, metatype = true, immediate = true)
 @Service
+@Properties(value = {
+                     @Property(name = DefaultRDFBridgeImpl.PROP_RESOURCE_SELECTOR, value = "rdf:type > skos:Concept"),
+                     @Property(name = DefaultRDFBridgeImpl.PROP_NAME, value = "rdfs:label"),
+                     @Property(name = DefaultRDFBridgeImpl.PROP_CHILDREN, cardinality = 1000, value = {"skos:narrower"}),
+                     @Property(name = DefaultRDFBridgeImpl.PROP_DEFAULT_CHILD_PREDICATE, value = "skos:narrower"),
+                     @Property(name = DefaultRDFBridgeImpl.PROP_CMS_PATH, value = "/rdfmaptest")})
 public class DefaultRDFBridgeImpl implements RDFBridge {
+    public static final String PROP_RESOURCE_SELECTOR = "org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.resourceSelector";
+    public static final String PROP_NAME = "org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.resourceNamePredicate";
+    public static final String PROP_CHILDREN = "org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.childrenPredicates";
+    public static final String PROP_DEFAULT_CHILD_PREDICATE = "org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.defaultChildPredicate";
+    public static final String PROP_CMS_PATH = "org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.contentRepositoryPath";
+
     private static final Logger log = LoggerFactory.getLogger(CMSAdapterVocabulary.class);
 
-    @Reference(cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, referenceInterface = RDFBridgeConfiguration.class, policy = ReferencePolicy.DYNAMIC, bind = "bindRDFBridgeConfiguration", unbind = "unbindRDFBridgeConfiguration", strategy = ReferenceStrategy.EVENT)
-    List<RDFBridgeConfiguration> defaultBridgeConfigs = new CopyOnWriteArrayList<RDFBridgeConfiguration>();
+    private UriRef targetResourcePredicate;
+    private UriRef targetResourceValue;
+    private UriRef nameResource;
+    private Map<UriRef,Object> targetChildrenMappings = new HashMap<UriRef,Object>();
+    private UriRef defaultChildPredicate;
+    private String cmsPath;
+
+    @SuppressWarnings("unchecked")
+    @Activate
+    protected void activate(ComponentContext context) throws ConfigurationException {
+        Dictionary<String,Object> properties = (Dictionary<String,Object>) context.getProperties();
+        parseTargetResourceConfig(properties);
+        parseURIConfig(PROP_NAME, properties);
+        parseChildrenMappings(properties);
+        parseURIConfig(PROP_DEFAULT_CHILD_PREDICATE, properties);
+        this.cmsPath = (String) checkProperty(properties, PROP_CMS_PATH, true);
+    }
 
     @Override
     public MGraph annotateGraph(Graph rawRDF) {
-        MGraph annotatedGraph = new SimpleMGraph(rawRDF);
-        addAnnotationsToGraph(annotatedGraph);
-        return annotatedGraph;
-    }
-
-    /**
-     * Adds annotations according to available {@link RDFBridgeConfiguration} instances<br>
-     * <br>
-     * It first select target resources by using the configurations obtained from
-     * {@link RDFBridgeConfiguration#getTargetPropertyResources()} and
-     * {@link RDFBridgeConfiguration#getTargetResourceValue()}.<br>
-     * <br>
-     * In the next step, parent/child relations are set according to configuration values obtained from
-     * {@link RDFBridgeConfiguration#getChildrenResources()}. In case of multiple children having same name,
-     * an integer value added to the end of the name incrementally e.g
-     * <b>name</b>,<b>name1</b>,<b>name2</b>,...<br>
-     * <br>
-     * Then property annotations are added to according configuration values obtained from
-     * {@link RDFBridgeConfiguration#getTargetPropertyResources()}. Name of a property is kept for each bridge
-     * to to make possible giving different names for the same property in different bridges.<br>
-     * <br>
-     * 
-     * @param graph
-     *            {@link MGraph} keeping the raw RDF data
-     */
-    private void addAnnotationsToGraph(MGraph graph) {
+        MGraph graph = new SimpleMGraph(rawRDF);
         LiteralFactory literalFactory = LiteralFactory.getInstance();
-        Map<UriRef,Object> children;
-        Map<UriRef,Object> properties;
-
-        for (RDFBridgeConfiguration config : defaultBridgeConfigs) {
-            children = config.getChildrenResources();
-            properties = config.getTargetPropertyResources();
-            Iterator<Triple> tripleIterator = graph.filter(null, config.getTargetResourcePredicate(),
-                config.getTargetResourceValue());
-            UriRef nameProp = config.getNameResource();
-
-            // add cms object annotations
-            while (tripleIterator.hasNext()) {
-                Triple t = tripleIterator.next();
-                NonLiteral subject = t.getSubject();
-                String name = RDFBridgeHelper.getResourceStringValue(subject, nameProp, graph);
-
-                // There should be a valid name for CMS Object
-                if (!name.contentEquals("")) {
-                    graph.add(new TripleImpl(subject, RDFBridgeHelper.RDF_TYPE,
-                            CMSAdapterVocabulary.CMS_OBJECT));
-
-                    // if this object has already has name and path annotations, it means that it's already
-                    // processed as child of another object. So, don't put new name and path annotations
-                    if (!graph.filter(subject, CMSAdapterVocabulary.CMS_OBJECT_NAME, null).hasNext()) {
-                        graph.add(new TripleImpl(subject, CMSAdapterVocabulary.CMS_OBJECT_NAME,
-                                literalFactory.createTypedLiteral(name)));
-                    }
+        Iterator<Triple> tripleIterator = graph.filter(null, targetResourcePredicate, targetResourceValue);
+        List<NonLiteral> processedURIs = new ArrayList<NonLiteral>();
 
-                    // check children and add child and parent annotations
-                    checkChildren(children, subject, graph);
-
-                    // check desired properties to be mapped
-                    checkProperties(properties, subject, config, graph);
+        // add cms object annotations
+        while (tripleIterator.hasNext()) {
+            Triple t = tripleIterator.next();
+            NonLiteral subject = t.getSubject();
+            String name = getObjectName(subject, nameResource, graph, false);
+
+            // There should be a valid name for CMS Object
+            if (!name.contentEquals("")) {
+                graph.add(new TripleImpl(subject, RDFBridgeHelper.RDF_TYPE, CMSAdapterVocabulary.CMS_OBJECT));
+                processedURIs.add(subject);
+
+                /*
+                 * if this object has already has name and path annotations, it means that it's already
+                 * processed as child of another object. So, don't put new name annotations
+                 */
+                if (!graph.filter(subject, CMSAdapterVocabulary.CMS_OBJECT_NAME, null).hasNext()) {
+                    graph.add(new TripleImpl(subject, CMSAdapterVocabulary.CMS_OBJECT_NAME, literalFactory
+                            .createTypedLiteral(name)));
                 }
+
+                // check children and add child and parent annotations
+                checkChildren(subject, processedURIs, graph);
             }
         }
+        RDFBridgeHelper.addPathAnnotations(cmsPath, processedURIs, graph);
+        return graph;
     }
 
-    private static void checkChildren(Map<UriRef,Object> children, NonLiteral objectURI, MGraph graph) {
+    private void checkChildren(NonLiteral objectURI, List<NonLiteral> processedURIs, MGraph graph) {
         LiteralFactory literalFactory = LiteralFactory.getInstance();
-        for (UriRef childPropURI : children.keySet()) {
+        for (UriRef childPropURI : targetChildrenMappings.keySet()) {
             Iterator<Triple> childrenIt = graph.filter(objectURI, childPropURI, null);
             Map<String,Integer> childNames = new HashMap<String,Integer>();
             while (childrenIt.hasNext()) {
@@ -134,7 +165,7 @@ public class DefaultRDFBridgeImpl implem
                 NonLiteral childSubject = new UriRef(RDFBridgeHelper.removeEndCharacters(child.getObject()
                         .toString()));
 
-                String childName = getNameOfProperty(childSubject, children.get(childPropURI), graph);
+                String childName = getChildName(childSubject, targetChildrenMappings.get(childPropURI), graph);
                 if (!childName.contentEquals("")) {
                     RDFBridgeHelper.removeExistingTriple(childSubject, CMSAdapterVocabulary.CMS_OBJECT_NAME,
                         graph);
@@ -143,7 +174,7 @@ public class DefaultRDFBridgeImpl implem
                     graph.add(new TripleImpl(childSubject, CMSAdapterVocabulary.CMS_OBJECT_PARENT_REF,
                             objectURI));
                     graph.add(new TripleImpl(childSubject, CMSAdapterVocabulary.CMS_OBJECT_NAME,
-                            literalFactory.createTypedLiteral(getChildName(childName, childNames))));
+                            literalFactory.createTypedLiteral(checkDuplicateChildName(childName, childNames))));
 
                 } else {
                     log.warn("Failed to obtain a name for child property: {}", childPropURI);
@@ -152,45 +183,51 @@ public class DefaultRDFBridgeImpl implem
         }
     }
 
-    private static void checkProperties(Map<UriRef,Object> properties,
-                                        NonLiteral subject,
-                                        RDFBridgeConfiguration bridge,
-                                        MGraph graph) {
+    private String getObjectName(NonLiteral subject,
+                                 UriRef namePredicate,
+                                 MGraph graph,
+                                 boolean tryTargetResourceNamePredicate) {
+        String name = "";
+        // try to get name through default CMS Vocabulary predicate
+        name = RDFBridgeHelper.getResourceStringValue(subject, CMSAdapterVocabulary.CMS_OBJECT_NAME, graph);
+        if (!name.contentEquals("")) {
+            return name;
+        }
 
-        LiteralFactory literalFactory = LiteralFactory.getInstance();
-        Map<UriRef,UriRef> propertiesNamesInBridge = new HashMap<UriRef,UriRef>();
-        for (UriRef propURI : properties.keySet()) {
-            String propertyName = getNameOfProperty(subject, properties.get(propURI), graph);
-            if (!propertyName.contentEquals("")) {
-                if (!propertiesNamesInBridge.containsKey(propURI)) {
-
-                    UriRef tempRef = new UriRef(propertyName + "Prop" + bridge.hashCode());
-                    propertiesNamesInBridge.put(propURI, tempRef);
-
-                    graph.add(new TripleImpl(tempRef, CMSAdapterVocabulary.CMS_OBJECT_PROPERTY_NAME,
-                            literalFactory.createTypedLiteral(propertyName)));
-                    graph.add(new TripleImpl(tempRef, CMSAdapterVocabulary.CMS_OBJECT_PROPERTY_URI, propURI));
-                }
-                graph.add(new TripleImpl(subject, CMSAdapterVocabulary.CMS_OBJECT_HAS_PROPERTY,
-                        propertiesNamesInBridge.get(propURI)));
-            } else {
-                log.warn("Failed to obtain a name for property: {}", propURI);
+        // if there is a configuration specifying the name try to obtain through it
+        if (namePredicate != null) {
+            name = RDFBridgeHelper.getResourceStringValue(subject, namePredicate, graph);
+            if (!name.contentEquals("")) {
+                return name;
+            }
+        }
+
+        // if this method is called from a child node try to obtain name by target resource name predicate
+        if (nameResource != null) {
+            name = RDFBridgeHelper.getResourceStringValue(subject, nameResource, graph);
+            if (!name.contentEquals("")) {
+                return name;
             }
         }
+
+        // failed to obtain name by the specified property assign local name from the URI
+        name = RDFBridgeHelper.extractLocalNameFromURI(subject);
+        return name;
     }
 
-    private static String getNameOfProperty(NonLiteral subject, Object nameProp, MGraph graph) {
+    private String getChildName(NonLiteral subject, Object nameProp, MGraph graph) {
         if (nameProp instanceof String) {
-            return (String) nameProp;
-        } else if (nameProp instanceof UriRef) {
-            return RDFBridgeHelper.getResourceStringValue(subject, (UriRef) nameProp, graph);
+            if (((String) nameProp).contentEquals("")) {
+                return getObjectName(subject, null, graph, true);
+            } else {
+                return (String) nameProp;
+            }
         } else {
-            log.warn("Only String and UriRef instance can be passed to specify property name");
-            return "";
+            return getObjectName(subject, (UriRef) nameProp, graph, true);
         }
     }
 
-    private static String getChildName(String candidateName, Map<String,Integer> childNames) {
+    private static String checkDuplicateChildName(String candidateName, Map<String,Integer> childNames) {
         Integer childNameCount = childNames.get(candidateName);
         if (childNameCount != null) {
             candidateName += (childNameCount + 1);
@@ -201,11 +238,185 @@ public class DefaultRDFBridgeImpl implem
         return candidateName;
     }
 
-    protected void bindRDFBridgeConfiguration(RDFBridgeConfiguration rdfBridgeConfiguration) {
-        defaultBridgeConfigs.add(rdfBridgeConfiguration);
+    @Override
+    public void annotateCMSGraph(MGraph cmsGraph) {
+        List<NonLiteral> roots = RDFBridgeHelper.getRootObjectsOfGraph(cmsPath, cmsGraph);
+        for (NonLiteral rootObjectURI : roots) {
+            applyReverseBridgeSettings(rootObjectURI, cmsGraph);
+            if (defaultChildPredicate != null) {
+                addChildrenAnnotations(rootObjectURI, cmsGraph);
+            }
+        }
+    }
+
+    private void addChildrenAnnotations(NonLiteral parentURI, MGraph graph) {
+        Iterator<Triple> children = graph.filter(null, CMSAdapterVocabulary.CMS_OBJECT_PARENT_REF, parentURI);
+        while (children.hasNext()) {
+            NonLiteral childURI = children.next().getSubject();
+            /*
+             * If parent has already a property referencing child, do not add a new subsumption relation.
+             * Otherwise, if children configurations has a single item use that property, if there are more
+             * than one children configuration use the default child predicate.
+             */
+            Iterator<Triple> childParentRelations = graph.filter(parentURI, null, childURI);
+            if (!childParentRelations.hasNext()) {
+                UriRef childPredicate;
+                if (targetChildrenMappings.size() == 1) {
+                    childPredicate = targetChildrenMappings.keySet().iterator().next();
+                } else {
+                    childPredicate = defaultChildPredicate;
+                }
+                graph.add(new TripleImpl(parentURI, childPredicate, childURI));
+                applyReverseBridgeSettings(childURI, graph);
+                addChildrenAnnotations(childURI, graph);
+            }
+        }
+    }
+
+    private void applyReverseBridgeSettings(NonLiteral subject, MGraph graph) {
+        graph.add(new TripleImpl(subject, targetResourcePredicate, targetResourceValue));
+        revertObjectName(subject, graph);
+    }
+
+    private void revertObjectName(NonLiteral objectURI, MGraph graph) {
+        if (nameResource != null) {
+            Iterator<Triple> it = graph.filter(objectURI, CMSAdapterVocabulary.CMS_OBJECT_NAME, null);
+            if (it.hasNext()) {
+                Triple nameProp = it.next();
+                Resource name = nameProp.getObject();
+                graph.remove(nameProp);
+                graph.add(new TripleImpl(objectURI, nameResource, name));
+            } else {
+                log.warn("Failed to find name property for URI: {}", objectURI);
+            }
+        }
+    }
+
+    @Override
+    public String getCMSPath() {
+        return this.cmsPath;
+    }
+
+    /*
+     * Methods to parse configurations
+     */
+
+    private void parseURIConfig(String config, Dictionary<String,Object> properties) {
+        Object value = null;
+        try {
+            value = checkProperty(properties, config, false);
+            if (value != null && !((String) value).trim().contentEquals("")) {
+                if (config.contentEquals(PROP_NAME)) {
+                    this.nameResource = parseUriRefFromConfig((String) value);
+                } else if (config.contentEquals(PROP_DEFAULT_CHILD_PREDICATE)) {
+                    this.defaultChildPredicate = parseUriRefFromConfig((String) value);
+                }
+            }
+        } catch (ConfigurationException e) {
+            log.warn("This configuration should be either empty or has one of the following formats:"
+                     + "\nskos:narrower" + "\nhttp://www.w3.org/2004/02/skos/core#narrower");
+        }
+    }
+
+    private void parseTargetResourceConfig(Dictionary<String,Object> properties) throws ConfigurationException {
+        String targetResourceConfig = (String) checkProperty(properties, PROP_RESOURCE_SELECTOR, true);
+        String[] configParts = parsePropertyConfig(targetResourceConfig);
+
+        this.targetResourcePredicate = parseUriRefFromConfig(configParts[0]);
+        this.targetResourceValue = parseUriRefFromConfig(configParts[1]);
+    }
+
+    private void parseChildrenMappings(Dictionary<String,Object> properties) {
+        Object value = null;
+        try {
+            value = checkProperty(properties, PROP_CHILDREN, false);
+        } catch (ConfigurationException e) {
+            // not the case
+        }
+        if (value != null) {
+            if (value instanceof String) {
+                getChildConfiguration((String) value);
+
+            } else if (value instanceof String[]) {
+                for (String config : (String[]) value) {
+                    getChildConfiguration(config);
+                }
+            }
+        }
+    }
+
+    private UriRef parseUriRefFromConfig(String config) {
+        return new UriRef(NamespaceEnum.getFullName(config));
+    }
+
+    private void getChildConfiguration(String config) {
+        try {
+            String[] configParts = parseChildrenConfig(config);
+            int configLength = configParts.length;
+
+            Object name = null;
+            if (configLength == 2) {
+                if (configParts[1].contains(":")) {
+                    if (RDFBridgeHelper.isShortNameResolvable(configParts[1])) {
+                        name = new UriRef(NamespaceEnum.getFullName(configParts[1]));
+                    } else {
+                        name = null;
+                    }
+                } else {
+                    name = configParts[1];
+                }
+            }
+
+            this.targetChildrenMappings.put(parseUriRefFromConfig(configParts[0]), name);
+
+        } catch (ConfigurationException e) {
+            log.warn("Failed to parse configuration value: {}", config);
+            log.warn("Configuration value should be in the format e.g skos:Definition > definition");
+        }
+    }
+
+    private Object checkProperty(Dictionary<String,Object> properties, String key, boolean required) throws ConfigurationException {
+        Object value = properties.get(key);
+        if (value == null) {
+            if (required) {
+                throw new ConfigurationException(key, "Failed to get value for this property");
+            } else {
+                return null;
+            }
+        } else {
+            return value;
+        }
+    }
+
+    private String[] parseChildrenConfig(String config) throws ConfigurationException {
+        String[] configParts = config.split(">");
+        int parts = configParts.length;
+
+        if (parts == 1 || parts == 2) {
+            for (int i = 0; i < parts; i++) {
+                configParts[i] = configParts[i].trim();
+            }
+        } else {
+            throw new ConfigurationException(PROP_CHILDREN,
+                    "Children resource configuration should have a value like one of the following three alternatives: "
+                            + "\nskos:narrower" + "\nskos:narrower > narrower"
+                            + "\nskos:narrawer > rdfs:label");
+        }
+        return configParts;
     }
 
-    protected void unbindRDFBridgeConfiguration(RDFBridgeConfiguration rdfBridgeConfiguration) {
-        defaultBridgeConfigs.remove(rdfBridgeConfiguration);
+    private String[] parsePropertyConfig(String config) throws ConfigurationException {
+        String[] configParts = config.split(">");
+        int parts = configParts.length;
+
+        if (parts == 1 || parts == 2) {
+            for (int i = 0; i < parts; i++) {
+                configParts[i] = configParts[i].trim();
+            }
+        } else {
+            throw new ConfigurationException(PROP_RESOURCE_SELECTOR,
+                    "Target resource and resource value should be seperated by a single'>' sign");
+        }
+        return configParts;
     }
 }

Modified: incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/RDFBridgeHelper.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/RDFBridgeHelper.java?rev=1161593&r1=1161592&r2=1161593&view=diff
==============================================================================
--- incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/RDFBridgeHelper.java (original)
+++ incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/RDFBridgeHelper.java Thu Aug 25 15:03:28 2011
@@ -4,22 +4,23 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
-import javax.jcr.PropertyType;
-
 import org.apache.clerezza.rdf.core.Literal;
+import org.apache.clerezza.rdf.core.LiteralFactory;
 import org.apache.clerezza.rdf.core.MGraph;
 import org.apache.clerezza.rdf.core.NonLiteral;
 import org.apache.clerezza.rdf.core.Resource;
 import org.apache.clerezza.rdf.core.Triple;
-import org.apache.clerezza.rdf.core.TypedLiteral;
 import org.apache.clerezza.rdf.core.UriRef;
+import org.apache.clerezza.rdf.core.impl.TripleImpl;
 import org.apache.stanbol.cmsadapter.servicesapi.helper.CMSAdapterVocabulary;
-import org.apache.stanbol.entityhub.servicesapi.defaults.NamespaceEnum;
+import org.apache.stanbol.cmsadapter.servicesapi.helper.NamespaceEnum;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.hp.hpl.jena.rdf.model.impl.Util;
+
 /**
- * Provides utility classes that are used parsing the RDF data
+ * Provides utility classes that are used during the RDF bridging process
  * 
  * @author suat
  * 
@@ -27,50 +28,100 @@ import org.slf4j.LoggerFactory;
 public class RDFBridgeHelper {
     private static final Logger log = LoggerFactory.getLogger(RDFBridgeHelper.class);
 
-    public static final UriRef RDF_TYPE = new UriRef(NamespaceEnum.rdf + "Type");
+    public static final UriRef RDF_TYPE = new UriRef(NamespaceEnum.rdf + "type");
 
-    private static final UriRef base64Uri = dataTypeURI("base64Binary");
-    private static final UriRef dateTimeUri = dataTypeURI("dateTime");
-    private static final UriRef booleanUri = dataTypeURI("boolean");
-    private static final UriRef stringUri = dataTypeURI("string");
-    private static final UriRef xsdInteger = dataTypeURI("integer");
-    private static final UriRef xsdInt = dataTypeURI("int");
-    private static final UriRef xsdShort = dataTypeURI("short");
-    private static final UriRef xsdLong = dataTypeURI("long");
-    private static final UriRef xsdDouble = dataTypeURI("double");
-    private static final UriRef xsdAnyURI = dataTypeURI("anyURI");
+    public static final UriRef base64Uri = dataTypeURI("base64Binary");
+    public static final UriRef dateTimeUri = dataTypeURI("dateTime");
+    public static final UriRef booleanUri = dataTypeURI("boolean");
+    public static final UriRef stringUri = dataTypeURI("string");
+    public static final UriRef xsdInteger = dataTypeURI("integer");
+    public static final UriRef xsdInt = dataTypeURI("int");
+    public static final UriRef xsdShort = dataTypeURI("short");
+    public static final UriRef xsdLong = dataTypeURI("long");
+    public static final UriRef xsdDouble = dataTypeURI("double");
+    public static final UriRef xsdAnyURI = dataTypeURI("anyURI");
 
     /**
-     * Gets a list of {@link NonLiteral} which indicates URIs of resources representing the root objects in
-     * the graph e.g the object that do not have {@code CMSAdapterVocabulary#CMS_OBJECT_PARENT_REF} property
+     * Extracts a list of {@link NonLiteral} which indicates URIs of resources representing the root objects
+     * in the graph e.g the object that do not have {@code CMSAdapterVocabulary#CMS_OBJECT_PARENT_REF}
+     * property. Returned URIs should also be included in the candidate URIs passed as a parameter.
      * 
-     * @param annotatedGraph
-     * @return
+     * @param candidates
+     *            candidate URI list
+     * @param graph
+     *            {@link MGraph} in which root URIs will be searched
+     * @return list of {@link NonLiteral}s
      */
-    public static List<NonLiteral> getRootObjetsOfGraph(MGraph annotatedGraph) {
-        List<NonLiteral> roots = new ArrayList<NonLiteral>();
-        Iterator<Triple> it = annotatedGraph.filter(null, RDF_TYPE, CMSAdapterVocabulary.CMS_OBJECT);
-        while (it.hasNext()) {
-            Triple t = it.next();
-            if (isRoot(t, annotatedGraph)) {
-                roots.add(t.getSubject());
+    public static List<NonLiteral> getRootObjetsOfGraph(List<NonLiteral> candidates, MGraph graph) {
+        List<NonLiteral> roots = getRootObjectsOfGraph(graph);
+        List<NonLiteral> rootsToBeReturned = new ArrayList<NonLiteral>();
+        for (NonLiteral root : roots) {
+            if (candidates.contains(root)) {
+                rootsToBeReturned.add(root);
             }
         }
-        return roots;
+        return rootsToBeReturned;
     }
 
-    public static List<NonLiteral> getRootObjectsOfGraph(MGraph annotatedGraph, List<NonLiteral> candidates) {
+    /**
+     * Extracts a list of {@link NonLiteral} which indicates URIs of resources representing the root objects
+     * in the graph e.g the object that do not have {link CMSAdapterVocabulary#CMS_OBJECT_PARENT_REF}
+     * property. Returned URIs should have {@link CMSAdapterVocabulary#CMS_OBJECT_NAME} assertions which have
+     * value equal with the <code>path</code> parameter passed. In other words, this method determines the
+     * root objects under the <code>path</code> specified.
+     * 
+     * @param path
+     *            content repository path
+     * @param graph
+     *            {@link MGraph} in which root URIs will be searched
+     * @return list of {@link NonLiteral}s
+     */
+    public static List<NonLiteral> getRootObjectsOfGraph(String path, MGraph graph) {
+        List<NonLiteral> roots = getRootObjectsOfGraph(graph);
+        List<NonLiteral> rootsToBeReturned = new ArrayList<NonLiteral>();
+        for (NonLiteral root : roots) {
+            if (isUnderAbsolutePath(path, root, graph)) {
+                rootsToBeReturned.add(root);
+            }
+        }
+        return rootsToBeReturned;
+    }
+
+    /**
+     * Extracts a list of {@link NonLiteral} which indicates URIs of resources representing the root objects
+     * in the graph e.g the object that do not have {link CMSAdapterVocabulary#CMS_OBJECT_PARENT_REF}
+     * property.
+     * 
+     * @param graph
+     *            {@link MGraph} in which root URIs will be searched
+     * @return list of {@link NonLiteral}s
+     */
+    public static List<NonLiteral> getRootObjectsOfGraph(MGraph graph) {
         List<NonLiteral> roots = new ArrayList<NonLiteral>();
-        Iterator<Triple> it = annotatedGraph.filter(null, RDF_TYPE, CMSAdapterVocabulary.CMS_OBJECT);
+        Iterator<Triple> it = graph.filter(null, RDF_TYPE, CMSAdapterVocabulary.CMS_OBJECT);
         while (it.hasNext()) {
             Triple t = it.next();
-            if (isRoot(t, annotatedGraph) && candidates.contains(t.getSubject())) {
+            if (isRoot(t, graph)) {
                 roots.add(t.getSubject());
             }
         }
         return roots;
     }
 
+    private static boolean isUnderAbsolutePath(String path, NonLiteral subject, MGraph graph) {
+        String name = getResourceStringValue(subject, CMSAdapterVocabulary.CMS_OBJECT_NAME, graph);
+        if (name.contentEquals("")) {
+            return false;
+        }
+        String objectPath = getResourceStringValue(subject, CMSAdapterVocabulary.CMS_OBJECT_PATH, graph);
+        int nameIndex = objectPath.lastIndexOf(name);
+        if (nameIndex == -1) {
+            return false;
+        }
+        String precedingPath = objectPath.substring(0, nameIndex);
+        return precedingPath.contentEquals(path) || precedingPath.contentEquals(path + "/");
+    }
+
     private static boolean isRoot(Triple cmsObjectTriple, MGraph graph) {
         NonLiteral subject = cmsObjectTriple.getSubject();
         if (graph.filter(subject, CMSAdapterVocabulary.CMS_OBJECT_PARENT_REF, null).hasNext()) {
@@ -100,17 +151,28 @@ public class RDFBridgeHelper {
     }
 
     /**
-     * Gets lexical form of {@code Triple} which is specified the <code>subject</code> and
-     * <code>propName</code> parameters if the target resource is an instance of {@link Literal}.
+     * Gets lexical form of the {@link Resource} of {@link Triple} which is specified the <code>subject</code>
+     * and <code>propName</code> parameters if the target resource is an instance of {@link Literal}.
      * 
      * @param subject
-     * @param propName
+     * @param predicate
      * @param graph
      * @return lexical value of specified resource it exists and an instance of {@link Literal}, otherwise it
      *         returns empty string
      */
-    public static String getResourceStringValue(NonLiteral subject, UriRef propName, MGraph graph) {
-        Resource r = getResource(subject, propName, graph);
+    public static String getResourceStringValue(NonLiteral subject, UriRef predicate, MGraph graph) {
+        Resource r = getResource(subject, predicate, graph);
+        return getResourceStringValue(r);
+    }
+
+    /**
+     * Gets lexical form of the specified {@link Resource} if it is an instance of {@link Literal}.
+     * 
+     * @param r
+     * @return lexical value of specified resource it is not null and an instance of {@link Literal},
+     *         otherwise it returns empty string
+     */
+    public static String getResourceStringValue(Resource r) {
         if (r != null) {
             if (r instanceof Literal) {
                 return ((Literal) r).getLexicalForm();
@@ -124,17 +186,32 @@ public class RDFBridgeHelper {
     }
 
     /**
-     * Gets {@link UriRef} from the {@link Resource} of {@link Triple} which is specified the
+     * Gets {@link UriRef} from the {@link Resource} of {@link Triple} which is specified by the
      * <code>subject</code> and <code>propName</code> parameters if the target resource is an instance of
      * {@link UriRef}.
      * 
      * @param subject
-     * @param propName
+     *            subject of the target triple
+     * @param predicate
+     *            predicate of the target triple
      * @param graph
-     * @return {@link UriRef} of resource if it exists and is instance of {@link UriRef}
+     *            graph which the target triple is in
+     * @return {@link UriRef} of resource if it exists and is instance of {@link UriRef}, otherwise
+     *         <code>null</code>
      */
-    public static UriRef getResourceURIValue(NonLiteral subject, UriRef propName, MGraph graph) {
-        Resource r = getResource(subject, propName, graph);
+    public static UriRef getResourceURIValue(NonLiteral subject, UriRef predicate, MGraph graph) {
+        Resource r = getResource(subject, predicate, graph);
+        return getResourceURIValue(r);
+    }
+
+    /**
+     * Gets {@link UriRef} from the specified {@link Resource}.
+     * 
+     * @param r
+     * @return {@link UriRef} of resource if is not <code>null</code> and instance of an {@link UriRef},
+     *         otherwise <code>null</code>
+     */
+    public static UriRef getResourceURIValue(Resource r) {
         if (r != null) {
             if (r instanceof UriRef) {
                 return new UriRef(removeEndCharacters(r.toString()));
@@ -148,6 +225,25 @@ public class RDFBridgeHelper {
     }
 
     /**
+     * Extracts a short URI e.g <b>skos:Concept</b> from a specified {@link Resource}.
+     * 
+     * @param r
+     * @return short URI if the resource is an instance of {@link Literal} or {@link UriRef}
+     */
+    public static String getShortURIFromResource(Resource r) {
+        String shortURI = "";
+        if (r instanceof Literal) {
+            shortURI = getResourceStringValue(r);
+        } else if (r instanceof UriRef) {
+            UriRef uri = getResourceURIValue(r);
+            shortURI = NamespaceEnum.getShortName(removeEndCharacters(uri.toString()));
+        } else {
+            log.warn("Unexpected resource type:{} of mixin type resource", r);
+        }
+        return shortURI;
+    }
+
+    /**
      * Remove first {@link Triple} specified with <code>subject</code> and <code>predicate</code> parameters
      * from the specified {@link MGraph}
      * 
@@ -176,48 +272,97 @@ public class RDFBridgeHelper {
     }
 
     /**
-     * Return related {@link PropertyType} according to data type of a {@link Resource} if it is an instance
-     * of {@link TypedLiteral} ot {@link UriRef}, otherwise it return {@code PropertyType#STRING} as default
-     * type.
+     * Tries to separate the local name from the given {@link NonLiteral}
      * 
-     * @param r
-     * @link {@link Resource} instance of which property type is demanded
-     * @return related {@link PropertyType}
+     * @param uri
+     *            absolute URI from which local name will be extracted
+     * @return extracted local name
      */
-    public static int getPropertyType(Resource r) {
-        if (r instanceof TypedLiteral) {
-            UriRef type = ((TypedLiteral) r).getDataType();
-            if (type.equals(stringUri)) {
-                return PropertyType.STRING;
-            } else if (type.equals(base64Uri)) {
-                return PropertyType.BINARY;
-            } else if (type.equals(booleanUri)) {
-                return PropertyType.BOOLEAN;
-            } else if (type.equals(dateTimeUri)) {
-                return PropertyType.DATE;
-            } else if (type.equals(xsdAnyURI)) {
-                return PropertyType.URI;
-            } else if (type.equals(xsdDouble)) {
-                return PropertyType.DOUBLE;
-            } else if (type.equals(xsdInt)) {
-                return PropertyType.DECIMAL;
-            } else if (type.equals(xsdInteger)) {
-                return PropertyType.DECIMAL;
-            } else if (type.equals(xsdLong)) {
-                return PropertyType.LONG;
-            } else if (type.equals(xsdShort)) {
-                return PropertyType.DECIMAL;
-            } else {
-                return PropertyType.STRING;
-            }
-        } else if (r instanceof UriRef) {
-            return PropertyType.URI;
-        } else {
-            return PropertyType.STRING;
+    public static String extractLocalNameFromURI(NonLiteral subject) {
+        String uri = RDFBridgeHelper.removeEndCharacters(subject.toString());
+        return uri.substring(Util.splitNamespace(uri));
+    }
+
+    /**
+     * Add path annotations to the resources whose rdf:Type's is {@link CMSAdapterVocabulary#CMS_OBJECT}.
+     * Paths of objects are constructed according to {@link CMSAdapterVocabulary#CMS_OBJECT_PARENT_REF}
+     * annotations among the objects.
+     * 
+     * @param rootPath
+     *            the path representing the location in the CMS. This will be added as a prefix in front of
+     *            the path annotations
+     * @param graph
+     *            containing the target resource to be annotated
+     */
+    public static void addPathAnnotations(String rootPath, List<NonLiteral> candidates, MGraph graph) {
+        // first detect root objects
+        List<NonLiteral> roots = getRootObjetsOfGraph(candidates, graph);
+
+        // assign paths to children recursively
+        LiteralFactory literalFactory = LiteralFactory.getInstance();
+        for (NonLiteral root : roots) {
+            assignChildrenPaths(rootPath, root, graph, literalFactory, true);
         }
     }
 
+    private static void assignChildrenPaths(String cmsRootPath,
+                                            NonLiteral root,
+                                            MGraph graph,
+                                            LiteralFactory literalFactory,
+                                            boolean firstLevel) {
+        String rootName = getResourceStringValue(root, CMSAdapterVocabulary.CMS_OBJECT_NAME, graph);
+        String rootPath = cmsRootPath;
+        if (firstLevel) {
+            rootPath = formRootPath(cmsRootPath, rootName);
+            graph.add(new TripleImpl(root, CMSAdapterVocabulary.CMS_OBJECT_PATH, literalFactory
+                    .createTypedLiteral(rootPath)));
+        }
+
+        Iterator<Triple> it = graph.filter(null, CMSAdapterVocabulary.CMS_OBJECT_PARENT_REF, root);
+        while (it.hasNext()) {
+            NonLiteral childSubject = it.next().getSubject();
+            String childName = getResourceStringValue(childSubject, CMSAdapterVocabulary.CMS_OBJECT_NAME,
+                graph);
+            String childPath = formRootPath(rootPath, childName);
+            graph.add(new TripleImpl(childSubject, CMSAdapterVocabulary.CMS_OBJECT_PATH, literalFactory
+                    .createTypedLiteral(childPath)));
+            assignChildrenPaths(childPath, childSubject, graph, literalFactory, false);
+        }
+    }
+
+    private static String formRootPath(String targetRootPath, String objectName) {
+        if (!targetRootPath.endsWith("/")) {
+            targetRootPath += "/";
+        }
+        return targetRootPath + objectName;
+    }
+
     private static UriRef dataTypeURI(String type) {
         return new UriRef(NamespaceEnum.xsd + type);
     }
+
+    /**
+     * Adds the specified <code>localName</code> at the end of the <code>baseURI</code>
+     * 
+     * @param baseURI
+     * @param localName
+     * @return concatenated URI
+     */
+    public static String appendLocalName(String baseURI, String localName) {
+        if (baseURI.endsWith("#") || baseURI.endsWith("/")) {
+            return baseURI + localName;
+        }
+        return baseURI + "#" + localName;
+    }
+
+    /**
+     * Returns if it is possible to get full URI of the specified short URI e.g <b>skos:Concept</b>
+     * 
+     * @param shortURI
+     * @return <code>true</code> if it is possible to get full URI of the specified short URI
+     */
+    public static boolean isShortNameResolvable(String shortURI) {
+        String fullName = NamespaceEnum.getFullName(shortURI);
+        return !fullName.contentEquals(shortURI);
+    }
 }

Modified: incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/RDFBridgeManager.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/RDFBridgeManager.java?rev=1161593&r1=1161592&r2=1161593&view=diff
==============================================================================
--- incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/RDFBridgeManager.java (original)
+++ incubator/stanbol/trunk/cmsadapter/core/src/main/java/org/apache/stanbol/cmsadapter/core/mapping/RDFBridgeManager.java Thu Aug 25 15:03:28 2011
@@ -21,6 +21,7 @@ import java.util.concurrent.CopyOnWriteA
 
 import org.apache.clerezza.rdf.core.Graph;
 import org.apache.clerezza.rdf.core.MGraph;
+import org.apache.clerezza.rdf.core.impl.SimpleMGraph;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
@@ -39,8 +40,9 @@ import org.slf4j.LoggerFactory;
 
 /**
  * This component keeps track of {@link RDFBridge}s and {@link RDFMapper}s in the environment and it provides
- * a method to submit RDF data to be annotated according to <code>RDFBridge</code>s. <code>RDFMapper</code>s
- * update repository based on the annotated RDF.
+ * a method to submit RDF data to be annotated according to <code>RDFBridge</code>s. Then
+ * <code>RDFMapper</code>s update repository based on the annotated RDF. It also allows generating RDF from
+ * the content repository.
  * 
  * @author suat
  * 
@@ -67,15 +69,13 @@ public class RDFBridgeManager {
      * 
      * @param connectionInfo
      *            credentials to access repository
-     * @param rootPath
-     *            path in which the root objects in the annotated graph will be stored
      * @param rawRDFData
      *            RDF to be annotated
      * @throws RepositoryAccessException
      * @throws RDFBridgeException
      */
-    public void storeRDFToRepository(ConnectionInfo connectionInfo, String rootPath, Graph rawRDFData) throws RepositoryAccessException,
-                                                                                                      RDFBridgeException {
+    public void storeRDFToRepository(ConnectionInfo connectionInfo, Graph rawRDFData) throws RepositoryAccessException,
+                                                                                     RDFBridgeException {
         if (rdfBridges.size() == 0) {
             log.info("There is no RDF Bridge to execute");
             return;
@@ -85,27 +85,59 @@ public class RDFBridgeManager {
         // session
         RDFMapper mapper = getRDFMapper(connectionInfo);
         RepositoryAccess repositoryAccess = accessManager.getRepositoryAccessor(connectionInfo);
+        if (repositoryAccess == null) {
+            log.warn("Failed to retrieve a repository access with the specified connection info");
+            return;
+        }
         Object session = repositoryAccess.getSession(connectionInfo);
 
         // Annotate raw RDF with CMS vocabulary annotations according to bridges
-        MGraph annotatedGraph;
+        MGraph annotatedGraph = new SimpleMGraph();
         for (RDFBridge bridge : rdfBridges) {
-            // first annotate raw RDF with
-            // TODO: it may be better to expand annotated graph accumulatively.
-            // Each annotation operation would add new ones onto already
-            // existing ones
-            annotatedGraph = bridge.annotateGraph(rawRDFData);
+            annotatedGraph.addAll(bridge.annotateGraph(rawRDFData));
+        }
+
+        // Store annotated RDF in repository
+        mapper.storeRDFinRepository(session, annotatedGraph);
+    }
+
+    /**
+     * This method gets the RDF from the content repository based on the path configurations of
+     * {@link RDFBridge}s and annotate them using {@link RDFBridge#annotateCMSGraph(MGraph)}.
+     * 
+     * @param connectionInfo
+     *            is the object that holds all necessary information to connect repository.
+     * @return {@link MGraph} formed by the aggregation of generated RDF for each RDF bridge
+     * @throws RepositoryAccessException
+     * @throws RDFBridgeException
+     */
+    public MGraph generateRDFFromRepository(ConnectionInfo connectionInfo) throws RepositoryAccessException,
+                                                                          RDFBridgeException {
+        if (rdfBridges.size() == 0) {
+            log.info("There is no RDF Bridge to execute");
+            return new SimpleMGraph();
+        }
 
-            // Store annotated RDF in repository
-            mapper.storeRDFinRepository(session, rootPath, annotatedGraph);
+        // According to connection type get RDF mapper, repository accessor,
+        // session
+        RDFMapper mapper = getRDFMapper(connectionInfo);
+        RepositoryAccess repositoryAccess = accessManager.getRepositoryAccessor(connectionInfo);
+        Object session = repositoryAccess.getSession(connectionInfo);
+
+        MGraph cmsGraph = new SimpleMGraph();
+        for (RDFBridge bridge : rdfBridges) {
+            MGraph generatedGraph = mapper.generateRDFFromRepository(session, bridge.getCMSPath());
+            bridge.annotateCMSGraph(generatedGraph);
+            cmsGraph.addAll(generatedGraph);
         }
+        return cmsGraph;
     }
 
     private RDFMapper getRDFMapper(ConnectionInfo connectionInfo) {
         RDFMapper mapper = null;
         String type = connectionInfo.getConnectionType();
         for (RDFMapper rdfMapper : rdfMappers) {
-            if (rdfMapper.getClass().getSimpleName().startsWith(type)) {
+            if (rdfMapper.canMap(type)) {
                 mapper = (RDFMapper) rdfMapper;
             }
         }

Modified: incubator/stanbol/trunk/cmsadapter/core/src/main/resources/OSGI-INF/metatype/metatype.properties
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/cmsadapter/core/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=1161593&r1=1161592&r2=1161593&view=diff
==============================================================================
--- incubator/stanbol/trunk/cmsadapter/core/src/main/resources/OSGI-INF/metatype/metatype.properties (original)
+++ incubator/stanbol/trunk/cmsadapter/core/src/main/resources/OSGI-INF/metatype/metatype.properties Thu Aug 25 15:03:28 2011
@@ -16,17 +16,20 @@
 #===============================================================================
 #Properties and Options used to configure RDF Bridges
 #===============================================================================
-org.apache.stanbol.cmsadapter.rdfbridge.name=Apache Stanbol CMS Adapter RDF Bridge Configurations
-org.apache.stanbol.cmsadapter.rdfbridge.description=This configuration panel allows to configure create bridges between CMS and RDF data
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.name=Apache Stanbol CMS Adapter Default RDF Bridge Configurations
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.description=This configuration panel allows to configure create bridges between a content repository and RDF data
 
-org.apache.stanbol.cmsadapter.rdfbridge.resourceSelector.name=Resource Selector
-org.apache.stanbol.cmsadapter.rdfbridge.resourceSelector.description=Provides obtaining specified resource from RDF data. Fetched resource are created as nodes in the CMS.
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.resourceSelector.name=Resource Selector
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.resourceSelector.description=This configuration is used to filter resources from the RDF data. It should have the syntax: rdf:Type > skos:Concept. This configuration states that triples having value skos:Concept of rdf:type</b> predicate will be filtered. And subject of selected triples indicates the resource to be created/updated as node/object in the repository. It is also acceptable to pass full URIs such as http://www.w3.org/1999/02/22-rdf-syntax-ns#type > http://www.w3.org/2004/02/skos/core#Concept.
 
-org.apache.stanbol.cmsadapter.rdfbridge.properties.name=Properties
-org.apache.stanbol.cmsadapter.rdfbridge.properties.description=Provides specifying target RDF resources to be created as properties of nodes in the CMS. Property names are also specified in these configuration.
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.resourceNamePredicate.name=Resource Name Predicate
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.resourceNamePredicate.description=This configuration indicates the predicate which points to the name of node/object to be created in the repository. It should indicate a single URI such as rdfs:label or http://www.w3.org/2000/01/rdf-schema#label. Actually name value is obtained through the triple (s,p,o) where s is one of the subjects filtered by the "Resource Selector" configuration, p is this parameter. This configuration is optional. If an empty configuration is passed name of the CMS objects will be set as the local name of the URI represented by s.
  
-org.apache.stanbol.cmsadapter.rdfbridge.children.name=Children
-org.apache.stanbol.cmsadapter.rdfbridge.children.description=Provides specifying target RDF resource to be created as child nodes in the CMS. Children names are also specified in these configuration.
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.childrenPredicates.name=Children
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.childrenPredicates.description=This configuration specifies the children of nodes/objects to be created in the repository. Value of this configuration should be like skos:narrower > narrowerObject or skos:narrower > rdfs:label. First option has same logic with the previous parameter. It determines the name of the child CMS object to be created/updated. In the second case, value rdfs:label predicate of resource representing child object will be set as the name of child object/node in the repository. This option would be useful to create hierarchies. It is also possible to set only predicate indicating the subsumption relations such as only skos:narrower. In this case name of the child resource will be obtained from the local name of URI representing this CMS object. This configuration is optional. 
 
-org.apache.stanbol.cmsadapter.rdfbridge.cmsPath.name=CMS Path
-org.apache.stanbol.cmsadapter.rdfbridge.cmsPath.description=Provides setting of CMS path in which new nodes will be created or existing ones will be searched.
\ No newline at end of file
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.defaultChildPredicate.name=Default Child Predicate
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.defaultChildPredicate.description=First of all, this configuration is used only when generating an RDF from the repository. If there are more than one child selector in previous configuration, it is not possible to detect the predicate that will be used as the child assertion. In that case, this configuration is used to set child assertion between parent and child objects. This configuration is optional. But if there is a case in which this configuration should be used and if it is not set, this causes missing assertions in the generated RDF.
+
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.contentRepositoryPath.name=Content Repository Path
+org.apache.stanbol.cmsadapter.core.mapping.DefaultRDFBridgeImpl.contentRepositoryPath.description=This property specifies the content repository path in which the new CMS objects will be created or existing ones will be updated.
\ No newline at end of file

Modified: incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/CMSAdapterVocabulary.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/CMSAdapterVocabulary.java?rev=1161593&r1=1161592&r2=1161593&view=diff
==============================================================================
--- incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/CMSAdapterVocabulary.java (original)
+++ incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/CMSAdapterVocabulary.java Thu Aug 25 15:03:28 2011
@@ -23,153 +23,134 @@ import com.hp.hpl.jena.rdf.model.Resourc
 import com.hp.hpl.jena.rdf.model.ResourceFactory;
 
 /**
- * This class contains necessary {@link Resource}s and {@link Property}ies that
- * are used in the scope of CMS Adapter component.
+ * This class contains necessary {@link Resource}s and {@link Property}ies that are used in the scope of CMS
+ * Adapter component.
  * 
  * @author suat
  * 
  */
 public class CMSAdapterVocabulary {
-	private static final String PATH_DELIMITER = "/";
+    private static final String PATH_DELIMITER = "/";
 
-	public static final String DEFAULT_NS_URI = "http://org.apache.stanbol";
+    public static final String DEFAULT_NS_URI = "http://www.apache.org/stanbol";
 
-	public static final String CMS_ADAPTER_VOCABULARY_PREFIX = "cmsad";
-	public static final String CMS_ADAPTER_VOCABULARY_URI = DEFAULT_NS_URI
-			+ PATH_DELIMITER + CMS_ADAPTER_VOCABULARY_PREFIX;
-
-	/*
-	 * Property to represent the path of the CMS item
-	 */
-	public static final String CMSAD_PATH_PROP_NAME = "path";
-	public static final Property CMSAD_PATH_PROP = property(
-			CMS_ADAPTER_VOCABULARY_URI, CMSAD_PATH_PROP_NAME);
-
-	/*
-	 * Property to keep mapping between resource name and its unique reference
-	 */
-	private static final String CMSAD_RESOURCE_REF_PROP_NAME = "resourceUniqueRef";
-	public static final Property CMSAD_RESOURCE_REF_PROP = property(
-			CMS_ADAPTER_VOCABULARY_URI, CMSAD_RESOURCE_REF_PROP_NAME);
-
-	/*
-	 * Property to keep source object type definition of a datatype property or
-	 * object property
-	 */
-	private static final String CMSAD_PROPERTY_SOURCE_OBJECT_PROP_NAME = "sourceObject";
-	public static final Property CMSAD_PROPERTY_SOURCE_OBJECT_PROP = property(
-			CMS_ADAPTER_VOCABULARY_URI, CMSAD_PROPERTY_SOURCE_OBJECT_PROP_NAME);
-
-	/**
-	 * Property to access metadata of a specific cms object.
-	 */
-	private static final String CMSAD_PROPERTY_CONTENT_ITEM_REF_NAME = "contentItemRef";
-	public static final Property CMSAD_PROPERTY_CONTENT_ITEM_REF = property(
-			CMS_ADAPTER_VOCABULARY_URI, CMSAD_PROPERTY_CONTENT_ITEM_REF_NAME);
-
-	/*
-	 * Properties to store connection info in the ontology
-	 */
-	// connection info resource
-	private static final String CONNECTION_INFO_RES_NAME = "connectionInfo";
-	public static final Resource CONNECTION_INFO_RES = resource(
-			CMS_ADAPTER_VOCABULARY_URI, CONNECTION_INFO_RES_NAME);
-
-	// workspace property
-	private static final String CONNECTION_WORKSPACE_PROP_NAME = "workspace";
-	public static final Property CONNECTION_WORKSPACE_PROP = property(
-			CMS_ADAPTER_VOCABULARY_URI, CONNECTION_WORKSPACE_PROP_NAME);
-
-	// username property
-	private static final String CONNECTION_USERNAME_PROP_NAME = "username";
-	public static final Property CONNECTION_USERNAME_PROP = property(
-			CMS_ADAPTER_VOCABULARY_URI, CONNECTION_USERNAME_PROP_NAME);
-
-	// password property
-	private static final String CONNECTION_PASSWORD_PROP_NAME = "password";
-	public static final Property CONNECTION_PASSWORD_PROP = property(
-			CMS_ADAPTER_VOCABULARY_URI, CONNECTION_PASSWORD_PROP_NAME);
-
-	// workspace url property
-	private static final String CONNECTION_WORKSPACE_URL_PROP_NAME = "workspaceURL";
-	public static final Property CONNECTION_WORKSPACE_URL_PROP = property(
-			CMS_ADAPTER_VOCABULARY_URI, CONNECTION_WORKSPACE_URL_PROP_NAME);
-
-	// connection type property
-	private static final String CONNECTION_TYPE_PROP_NAME = "connectionType";
-	public static final Property CONNECTION_TYPE_PROP = property(
-			CMS_ADAPTER_VOCABULARY_URI, CONNECTION_TYPE_PROP_NAME);
-
-	/*
-	 * Properties to store bridge definitions
-	 */
-	// bridge definitions resource
-	private static final String BRIDGE_DEFINITIONS_RES_NAME = "bridgeDefinitions";
-	public static final Resource BRIDGE_DEFINITIONS_RES = resource(
-			CMS_ADAPTER_VOCABULARY_URI, BRIDGE_DEFINITIONS_RES_NAME);
-
-	// property to keep bridge definitions
-	private static final String BRIDGE_DEFINITIONS_CONTENT_PROP_NAME = "content";
-	public static final Property BRIDGE_DEFINITIONS_CONTENT_PROP = property(
-			CMS_ADAPTER_VOCABULARY_URI, BRIDGE_DEFINITIONS_CONTENT_PROP_NAME);
-
-	private static Property property(String URI, String local) {
-		URI = OntologyResourceHelper.addResourceDelimiter(URI);
-		return ResourceFactory.createProperty(URI, local);
-	}
-
-	private static Resource resource(String URI, String local) {
-		URI = OntologyResourceHelper.addResourceDelimiter(URI);
-		return ResourceFactory.createResource(URI + local);
-	}
-
-	/*
-	 * CMS Vocabulary Annotations:
-	 * 
-	 * Below UriRef instances are used while annotating external RDF data. They
-	 * form a standard vocabulary to consisting of content repository elements.
-	 * Through this standard vocabulary, annotated RDF is reflected into the
-	 * content repository.
-	 */
-	/**
-	 * Represent the RDF type of CMS Object in the content management system
-	 */
-	public static final UriRef CMS_OBJECT = new UriRef(
-			CMS_ADAPTER_VOCABULARY_URI + PATH_DELIMITER + "CMSObject");
-
-	/**
-	 * Represents a reference to name of a CMS Object
-	 */
-	public static final UriRef CMS_OBJECT_NAME = new UriRef(
-			CMS_ADAPTER_VOCABULARY_URI + "#name");
-
-	/**
-	 * Represents a reference to path of a CMS Object
-	 */
-	public static final UriRef CMS_OBJECT_PATH = new UriRef(
-			CMS_ADAPTER_VOCABULARY_URI + "#path");
-
-	/**
-	 * Represents a reference to parent of a CMS Object
-	 */
-	public static final UriRef CMS_OBJECT_PARENT_REF = new UriRef(
-			CMS_ADAPTER_VOCABULARY_URI + "#parentRef");
-
-	/**
-	 * Represents a reference to a property of a CMS Object
-	 */
-	public static final UriRef CMS_OBJECT_HAS_PROPERTY = new UriRef(
-			CMS_ADAPTER_VOCABULARY_URI + "#hasProperty");
-
-	/**
-	 * Represents a reference to name of a property of a CMS Object
-	 */
-	public static final UriRef CMS_OBJECT_PROPERTY_NAME = new UriRef(
-			CMS_ADAPTER_VOCABULARY_URI + "#propertyName");
-
-	/**
-	 * Represents a reference to URI of a property of a CMS Object
-	 */
-	public static final UriRef CMS_OBJECT_PROPERTY_URI = new UriRef(
-			CMS_ADAPTER_VOCABULARY_URI + "#propertyURI");
+    public static final String CMS_ADAPTER_VOCABULARY_PREFIX = "cms";
+    public static final String CMS_ADAPTER_VOCABULARY_URI = DEFAULT_NS_URI + PATH_DELIMITER
+                                                            + CMS_ADAPTER_VOCABULARY_PREFIX;
+
+    /*
+     * Property to represent the path of the CMS item
+     */
+    public static final String CMSAD_PATH_PROP_NAME = "path";
+    public static final Property CMSAD_PATH_PROP = property(CMS_ADAPTER_VOCABULARY_URI, CMSAD_PATH_PROP_NAME);
+
+    /*
+     * Property to keep mapping between resource name and its unique reference
+     */
+    private static final String CMSAD_RESOURCE_REF_PROP_NAME = "resourceUniqueRef";
+    public static final Property CMSAD_RESOURCE_REF_PROP = property(CMS_ADAPTER_VOCABULARY_URI,
+        CMSAD_RESOURCE_REF_PROP_NAME);
+
+    /*
+     * Property to keep source object type definition of a datatype property or object property
+     */
+    private static final String CMSAD_PROPERTY_SOURCE_OBJECT_PROP_NAME = "sourceObject";
+    public static final Property CMSAD_PROPERTY_SOURCE_OBJECT_PROP = property(CMS_ADAPTER_VOCABULARY_URI,
+        CMSAD_PROPERTY_SOURCE_OBJECT_PROP_NAME);
+
+    /**
+     * Property to access metadata of a specific cms object.
+     */
+    private static final String CMSAD_PROPERTY_CONTENT_ITEM_REF_NAME = "contentItemRef";
+    public static final Property CMSAD_PROPERTY_CONTENT_ITEM_REF = property(CMS_ADAPTER_VOCABULARY_URI,
+        CMSAD_PROPERTY_CONTENT_ITEM_REF_NAME);
+
+    /*
+     * Properties to store connection info in the ontology
+     */
+    // connection info resource
+    private static final String CONNECTION_INFO_RES_NAME = "connectionInfo";
+    public static final Resource CONNECTION_INFO_RES = resource(CMS_ADAPTER_VOCABULARY_URI,
+        CONNECTION_INFO_RES_NAME);
+
+    // workspace property
+    private static final String CONNECTION_WORKSPACE_PROP_NAME = "workspace";
+    public static final Property CONNECTION_WORKSPACE_PROP = property(CMS_ADAPTER_VOCABULARY_URI,
+        CONNECTION_WORKSPACE_PROP_NAME);
+
+    // username property
+    private static final String CONNECTION_USERNAME_PROP_NAME = "username";
+    public static final Property CONNECTION_USERNAME_PROP = property(CMS_ADAPTER_VOCABULARY_URI,
+        CONNECTION_USERNAME_PROP_NAME);
+
+    // password property
+    private static final String CONNECTION_PASSWORD_PROP_NAME = "password";
+    public static final Property CONNECTION_PASSWORD_PROP = property(CMS_ADAPTER_VOCABULARY_URI,
+        CONNECTION_PASSWORD_PROP_NAME);
+
+    // workspace url property
+    private static final String CONNECTION_WORKSPACE_URL_PROP_NAME = "workspaceURL";
+    public static final Property CONNECTION_WORKSPACE_URL_PROP = property(CMS_ADAPTER_VOCABULARY_URI,
+        CONNECTION_WORKSPACE_URL_PROP_NAME);
+
+    // connection type property
+    private static final String CONNECTION_TYPE_PROP_NAME = "connectionType";
+    public static final Property CONNECTION_TYPE_PROP = property(CMS_ADAPTER_VOCABULARY_URI,
+        CONNECTION_TYPE_PROP_NAME);
+
+    /*
+     * Properties to store bridge definitions
+     */
+    // bridge definitions resource
+    private static final String BRIDGE_DEFINITIONS_RES_NAME = "bridgeDefinitions";
+    public static final Resource BRIDGE_DEFINITIONS_RES = resource(CMS_ADAPTER_VOCABULARY_URI,
+        BRIDGE_DEFINITIONS_RES_NAME);
+
+    // property to keep bridge definitions
+    private static final String BRIDGE_DEFINITIONS_CONTENT_PROP_NAME = "content";
+    public static final Property BRIDGE_DEFINITIONS_CONTENT_PROP = property(CMS_ADAPTER_VOCABULARY_URI,
+        BRIDGE_DEFINITIONS_CONTENT_PROP_NAME);
+
+    private static Property property(String URI, String local) {
+        URI = OntologyResourceHelper.addResourceDelimiter(URI);
+        return ResourceFactory.createProperty(URI, local);
+    }
+
+    private static Resource resource(String URI, String local) {
+        URI = OntologyResourceHelper.addResourceDelimiter(URI);
+        return ResourceFactory.createResource(URI + local);
+    }
+
+    /*
+     * CMS Vocabulary Annotations:
+     * 
+     * Below UriRef instances are used while annotating external RDF data. They form a standard vocabulary to
+     * consisting of content repository elements. Through this standard vocabulary, annotated RDF is reflected
+     * into the content repository.
+     */
+    /**
+     * Represent the RDF type of CMS Object in the content management system
+     */
+    public static final UriRef CMS_OBJECT = new UriRef(CMS_ADAPTER_VOCABULARY_URI + "#CMSObject");
+
+    /**
+     * Represents a reference to name of a CMS Object
+     */
+    public static final UriRef CMS_OBJECT_NAME = new UriRef(CMS_ADAPTER_VOCABULARY_URI + "#name");
+
+    /**
+     * Represents a reference to path of a CMS Object
+     */
+    public static final UriRef CMS_OBJECT_PATH = new UriRef(CMS_ADAPTER_VOCABULARY_URI + "#path");
+
+    /**
+     * Represents a reference to parent of a CMS Object
+     */
+    public static final UriRef CMS_OBJECT_PARENT_REF = new UriRef(CMS_ADAPTER_VOCABULARY_URI + "#parentRef");
+
+    /**
+     * Represents a reference to URI representing a CMS Object. It is used to identify CMS Objects in CMS as
+     * in the original RDF.
+     */
+    public static final UriRef CMS_OBJECT_HAS_URI = new UriRef(CMS_ADAPTER_VOCABULARY_URI + "#hasURI");
 }

Added: incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/NamespaceEnum.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/NamespaceEnum.java?rev=1161593&view=auto
==============================================================================
--- incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/NamespaceEnum.java (added)
+++ incubator/stanbol/trunk/cmsadapter/servicesapi/src/main/java/org/apache/stanbol/cmsadapter/servicesapi/helper/NamespaceEnum.java Thu Aug 25 15:03:28 2011
@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.stanbol.cmsadapter.servicesapi.helper;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Defines commonly used name spaces to prevent multiple definitions in several classes.
+ * 
+ * TODO: This class was directly adapted from the Entityhub services api. It would be better to have a common
+ * namespace enum throughout the Stanbol.
+ * 
+ */
+public enum NamespaceEnum {
+
+    // Namespaces defined by the entityhub
+    entityhubModel("entityhub", "http://www.iks-project.eu/ontology/rick/model/"),
+    entityhubQuery("entityhub-query", "http://www.iks-project.eu/ontology/rick/query/"),
+    // Namespaces defined by the CMS Adapter
+    cms("http://www.apache.org/stanbol/cms#"),
+    // First the XML Namespaces
+    xsd("http://www.w3.org/2001/XMLSchema#"),
+    xsi("http://www.w3.org/2001/XMLSchema-instance#"),
+    xml("http://www.w3.org/XML/1998/namespace#"),
+    // Start with the semantic Web Namespaces
+    rdf("http://www.w3.org/1999/02/22-rdf-syntax-ns#"),
+    rdfs("http://www.w3.org/2000/01/rdf-schema#"),
+    owl("http://www.w3.org/2002/07/owl#"),
+    // CMIS related
+    atom("http://www.w3.org/2005/Atom"),
+    cmis("http://docs.oasis-open.org/ns/cmis/core/200908/"),
+    cmisRa("cmis-ra", "http://docs.oasis-open.org/ns/cmis/restatom/200908/"),
+    // now the JCR related Namespaces
+    jcr("jcr", "http://www.jcp.org/jcr/1.0/"),
+    jcrSv("sv", "http://www.jcp.org/jcr/sv/1.0/"),
+    jcrNt("nt", "http://www.jcp.org/jcr/nt/1.0/"),
+    jcrMix("mix", "http://www.jcp.org/jcr/mix/1.0/"),
+    // Some well known Namespaces of Ontologies
+    geo("http://www.w3.org/2003/01/geo/wgs84_pos#"),
+    georss("http://www.georss.org/georss/"),
+    dcElements("dc-elements", "http://purl.org/dc/elements/1.1/"),
+    dcTerms("dc", "http://purl.org/dc/terms/"), // Entityhub prefers DC-Terms, therefore use the "dc" prefix
+                                                // for the terms name space
+    foaf("http://xmlns.com/foaf/0.1/"),
+    vCal("http://www.w3.org/2002/12/cal#"),
+    vCard("http://www.w3.org/2001/vcard-rdf/3.0#"),
+    skos("http://www.w3.org/2004/02/skos/core#"),
+    sioc("http://rdfs.org/sioc/ns#"),
+    siocTypes("sioc-types", "http://rdfs.org/sioc/types#"),
+    bio("dc-bio", "http://purl.org/vocab/bio/0.1/"),
+    rss("http://purl.org/rss/1.0/"),
+    goodRelations("gr", "http://purl.org/goodrelations/v1#"),
+    swrc("http://swrc.ontoware.org/ontology#"), // The Semantic Web for Research Communities Ontology
+    // Linked Data Ontologies
+    dbpediaOnt("dbp-ont", "http://dbpedia.org/ontology/"),
+    dbpediaProp("dbp-prop", "http://dbpedia.org/property/"),
+    geonames("http://www.geonames.org/ontology#"),
+    // copyright and license
+    cc("http://creativecommons.org/ns#"),
+    // Schema.org (see http://schema.org/docs/schemaorg.owl for the Ontology)
+    schema("http://schema.org/", true), ;
+    /**
+     * The logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(NamespaceEnum.class);
+
+    private final String ns;
+    private final String prefix;
+    private final boolean defaultPrefix;
+
+    /**
+     * Defines a namespace that used the {@link #name()} as prefix.
+     * 
+     * @param ns
+     *            the namespace. MUST NOT be NULL nor empty
+     */
+    NamespaceEnum(String ns) {
+        this(null, ns, false);
+    }
+
+    /**
+     * Defines a namespace by using the {@link #name()} as prefix. If <code>true</code> is parsed a second
+     * parameter this namespace is marked as the default
+     * <p>
+     * <b>NOTE: </b> Only a single namespace can be defined as default. In case multiple namespaces are marked
+     * as default the one with the lowest {@link #ordinal()} will be used as default. This will be the topmost
+     * entry in this enumeration.
+     * 
+     * @param ns
+     *            the namespace. MUST NOT be <code>null</code> nor empty
+     * @param defaultPrefix
+     *            the default namespace indicator
+     */
+    NamespaceEnum(String ns, boolean defaultPrefix) {
+        this(null, ns, defaultPrefix);
+    }
+
+    /**
+     * Defines a namespace with a customised prefix. This should be used if the prefix needs to be different
+     * as the {@link #name()} of the enumeration entry.
+     * 
+     * @param prefix
+     *            the prefix. If <code>null</code> the {@link #name()} is used. MUST NOT be an empty string
+     * @param ns
+     *            the namespace. MUST NOT be <code>null</code> nor empty
+     */
+    NamespaceEnum(String prefix, String ns) {
+        this(prefix, ns, false);
+    }
+
+    /**
+     * Defines a namespace with a customised prefix. This should be used if the prefix needs to be different
+     * as the {@link #name()} of the enumeration entry.
+     * <p>
+     * <b>NOTE: </b> Only a single namespace can be defined as default. In case multiple namespaces are marked
+     * as default the one with the lowest {@link #ordinal()} will be used as default. This will be the topmost
+     * entry in this enumeration.
+     * 
+     * @param prefix
+     *            the prefix. If <code>null</code> the {@link #name()} is used. MUST NOT be an empty string
+     * @param ns
+     *            the namespace. MUST NOT be <code>null</code> nor empty
+     * @param defaultPrefix
+     *            the default namespace indicator
+     */
+    NamespaceEnum(String prefix, String ns, boolean defaultPrefix) {
+        if (ns == null || ns.isEmpty()) {
+            throw new IllegalArgumentException("The namespace MUST NOT be NULL nor empty");
+        }
+        this.ns = ns;
+        if (prefix == null) {
+            this.prefix = name();
+        } else if (prefix.isEmpty()) {
+            throw new IllegalArgumentException("The prefix MUST NOT be emtpty."
+                                               + "Use NULL to use the name or parse the prefix to use");
+        } else {
+            this.prefix = prefix;
+        }
+        this.defaultPrefix = defaultPrefix;
+    }
+
+    public String getNamespace() {
+        return ns;
+    }
+
+    public String getPrefix() {
+        return prefix == null ? name() : prefix;
+    }
+
+    @Override
+    public String toString() {
+        return ns;
+    }
+
+    /*
+     * ==== Code for Lookup Methods based on Prefix and Namespace ====
+     */
+    private final static Map<String,NamespaceEnum> prefix2Namespace;
+    private final static Map<String,NamespaceEnum> namespace2Prefix;
+    private final static NamespaceEnum defaultNamespace;
+    static {
+        Map<String,NamespaceEnum> p2n = new HashMap<String,NamespaceEnum>();
+        Map<String,NamespaceEnum> n2p = new HashMap<String,NamespaceEnum>();
+        // The Exceptions are only thrown to check that this Enum is configured
+        // correctly!
+        NamespaceEnum defaultNs = null;
+        for (NamespaceEnum entry : NamespaceEnum.values()) {
+            if (entry.isDefault()) {
+                if (defaultNs == null) {
+                    defaultNs = entry;
+                } else {
+                    log.warn("Found multiple default namespace definitions! Will use the one with the lowest ordinal value.");
+                    log.warn(" > used default: prefix:{}, namespace:{}, ordinal:{}",
+                        new Object[] {defaultNs.getPrefix(), defaultNs.getNamespace(), defaultNs.ordinal()});
+                    log.warn(" > this one    : prefix:{}, namespace:{}, ordinal:{}",
+                        new Object[] {entry.getPrefix(), entry.getNamespace(), entry.ordinal()});
+                }
+            }
+            if (p2n.containsKey(entry.getPrefix())) {
+                throw new IllegalStateException(String.format(
+                    "Prefix %s used for multiple namespaces: %s and %s", entry.getPrefix(),
+                    p2n.get(entry.getPrefix()), entry.getNamespace()));
+            } else {
+                log.debug("add {} -> {} mapping", entry.getPrefix(), entry.getNamespace());
+                p2n.put(entry.getPrefix(), entry);
+            }
+            if (n2p.containsKey(entry.getNamespace())) {
+                throw new IllegalStateException(String.format(
+                    "Multiple Prefixs %s and %s for namespaces: %s", entry.getPrefix(),
+                    p2n.get(entry.getNamespace()), entry.getNamespace()));
+            } else {
+                log.debug("add {} -> {} mapping", entry.getNamespace(), entry.getPrefix());
+                n2p.put(entry.getNamespace(), entry);
+            }
+        }
+        prefix2Namespace = Collections.unmodifiableMap(p2n);
+        namespace2Prefix = Collections.unmodifiableMap(n2p);
+        defaultNamespace = defaultNs;
+    }
+
+    /**
+     * Getter for the {@link NamespaceEnum} entry based on the string namespace
+     * 
+     * @param namespace
+     *            the name space
+     * @return the {@link NamespaceEnum} entry or <code>null</code> if the prased namespace is not present
+     */
+    public static NamespaceEnum forNamespace(String namespace) {
+        return namespace2Prefix.get(namespace);
+    }
+
+    /**
+     * Getter for the {@link NamespaceEnum} entry based on the prefix
+     * 
+     * @param prefix
+     *            the prefix or <code>null</code> to get the default namespace
+     * @return the {@link NamespaceEnum} entry or <code>null</code> if the prased prefix is not present
+     */
+    public static NamespaceEnum forPrefix(String prefix) {
+        return prefix == null ? defaultNamespace : prefix2Namespace.get(prefix);
+    }
+
+    /**
+     * Lookup if the parsed short URI (e.g "rdfs:label") uses one of the registered prefixes of this
+     * Enumeration of if the parsed short URI uses the default namespace (e.g. "name"). In case the prefix
+     * could not be found the parsed URI is returned unchanged
+     * 
+     * @param shortUri
+     *            the short URI
+     * @return the full URI if the parsed shortUri uses a prefix defined by this Enumeration. Otherwise the
+     *         parsed value.
+     */
+    public static String getFullName(String shortUri) {
+        if (shortUri == null) {
+            return null;
+        }
+        int index = shortUri.indexOf(':');
+        if (index > 0) {
+            NamespaceEnum namespace = NamespaceEnum.forPrefix(shortUri.substring(0, index));
+            if (namespace != null) {
+                shortUri = namespace.getNamespace() + shortUri.substring(index + 1);
+            }
+        } else if (defaultNamespace != null) {
+            shortUri = defaultNamespace.getNamespace() + shortUri;
+        }
+        return shortUri;
+    }
+
+    /**
+     * Parsed the namespace of the parsed full URI by searching the last occurrence of '#' or '/' and than
+     * looks if the namespace is part of this enumeration. If a namesoace is found it is replaced by the
+     * registered prefix. If not the parsed URI is resturned
+     * 
+     * @param fullUri
+     *            the full uri to convert
+     * @return the converted URI or the parsed value of <code>null</code> was parsed, no local name was
+     *         present (e.g. if the namespace itself was parsed) or the parsed namespace is not known.
+     */
+    public static String getShortName(String fullUri) {
+        if (fullUri == null) {
+            return fullUri;
+        }
+        int index = Math.max(fullUri.lastIndexOf('#'), fullUri.lastIndexOf('/'));
+        // do not convert if the parsed uri does not contain a local name
+        if (index > 0 && index + 1 < fullUri.length()) {
+            String ns = fullUri.substring(0, index + 1);
+            NamespaceEnum namespace = namespace2Prefix.get(ns);
+            if (namespace != null) {
+                return namespace.getPrefix() + ':' + fullUri.substring(index + 1);
+            }
+        }
+        return fullUri;
+    }
+
+    /**
+     * @return the defaultPrefix
+     */
+    public boolean isDefault() {
+        return defaultPrefix;
+    }
+}