jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r1155283 - in /jackrabbit/trunk: jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/ jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/
Date Tue, 09 Aug 2011 09:33:30 GMT
Author: angela
Date: Tue Aug  9 09:33:30 2011
New Revision: 1155283

URL: http://svn.apache.org/viewvc?rev=1155283&view=rev
Log:
JCR-3042 - jcr-commons: add cnd writer functionality

Added:
    jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefWriter.java
  (with props)
Modified:
    jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java

Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefWriter.java?rev=1155283&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefWriter.java
(added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefWriter.java
Tue Aug  9 09:33:30 2011
@@ -0,0 +1,555 @@
+/*
+ * 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.jackrabbit.commons.cnd;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.commons.query.qom.Operator;
+import org.apache.jackrabbit.util.ISO9075;
+import org.apache.jackrabbit.util.Text;
+
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.nodetype.NodeDefinition;
+import javax.jcr.nodetype.NodeTypeDefinition;
+import javax.jcr.nodetype.PropertyDefinition;
+import javax.jcr.query.qom.QueryObjectModelConstants;
+import javax.jcr.version.OnParentVersionAction;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Prints node type defs in a compact notation
+ * Print Format:
+ * <ex = "http://apache.org/jackrabbit/example">
+ * [ex:NodeType] > ex:ParentType1, ex:ParentType2
+ * orderable mixin
+ *   - ex:property (STRING) = 'default1', 'default2'
+ *     primary mandatory autocreated protected multiple VERSION
+ *     < 'constraint1', 'constraint2'
+ *   + ex:node (ex:reqType1, ex:reqType2) = ex:defaultType
+ *     mandatory autocreated protected multiple VERSION
+ */
+public class CompactNodeTypeDefWriter {
+
+    /**
+     * the indention string
+     */
+    private static final String INDENT = "  ";
+
+    private static final String ANY = "*";
+
+    /**
+     * Helper to retrieve the namespace URI for a given prefix.
+     */
+    private final NamespaceMapping nsMapping;
+
+    /**
+     * the underlying writer
+     */
+    private Writer out;
+
+    /**
+     * special writer used for namespaces
+     */
+    private Writer nsWriter;
+
+    /**
+     * namespaces(prefixes) that are used
+     */
+    private final Set<String> usedNamespaces = new HashSet<String>();
+
+    /**
+     * Creates a new nodetype writer based on a session
+     *
+     * @param out the underlying writer
+     * @param session repository session
+     * @param includeNS if <code>true</code> all used namespace decl. are also
+     *                  written to the writer
+     */
+    public CompactNodeTypeDefWriter(Writer out, final Session session, boolean includeNS)
{
+        this(out, new DefaultNamespaceMapping(session), includeNS);
+    }
+
+    /**
+     * Creates a new nodetype writer based on a session
+     *
+     * @param out the underlying writer
+     * @param nsMapping the mapping from prefix to namespace URI.
+     * @param includeNS if <code>true</code> all used namespace decl. are also
+     *                  written to the writer
+     */
+    public CompactNodeTypeDefWriter(Writer out, NamespaceMapping nsMapping, boolean includeNS)
{
+        this.nsMapping = nsMapping;
+        if (includeNS) {
+            this.out = new StringWriter();
+            this.nsWriter = out;
+        } else {
+            this.out = out;
+            this.nsWriter = null;
+        }
+    }
+
+    /**
+     * Writes the given list of QNodeTypeDefinition to the output writer including the
+     * used namespaces.
+     *
+     * @param defs collection of definitions
+     * @param session session
+     * @param out output writer
+     * @throws java.io.IOException if an I/O error occurs
+     */
+    public static void write(Collection<NodeTypeDefinition> defs,
+                             Session session, Writer out) throws IOException {
+        CompactNodeTypeDefWriter w = new CompactNodeTypeDefWriter(out, session, true);
+        for (NodeTypeDefinition def : defs) {
+            w.write(def);
+        }
+        w.close();
+    }
+
+    /**
+     * Writes the given list of QNodeTypeDefinition to the output writer
+     * including the used namespaces.
+     *
+     * @param defs collection of definitions
+     * @param nsMapping the mapping from prefix to namespace URI.
+     * @param out output writer
+     * @throws java.io.IOException if an I/O error occurs
+     */
+    public static void write(Collection<NodeTypeDefinition> defs,
+                             NamespaceMapping nsMapping, Writer out) throws IOException {
+        CompactNodeTypeDefWriter w = new CompactNodeTypeDefWriter(out, nsMapping, true);
+        for (NodeTypeDefinition def : defs) {
+            w.write(def);
+        }
+        w.close();
+    }
+
+    /**
+     * Write one NodeTypeDefinition to this writer
+     *
+     * @param ntd node type definition
+     * @throws IOException if an I/O error occurs
+     */
+    public void write(NodeTypeDefinition ntd) throws IOException {
+        writeName(ntd);
+        writeSupertypes(ntd);
+        writeOptions(ntd);
+        PropertyDefinition[] pdefs = ntd.getDeclaredPropertyDefinitions();
+        if (pdefs != null) {
+            for (PropertyDefinition pd : pdefs) {
+                writePropDef(pd);
+            }
+        }
+        NodeDefinition[] ndefs = ntd.getDeclaredChildNodeDefinitions();
+        if (ndefs != null) {
+            for (NodeDefinition nd : ndefs) {
+                writeNodeDef(nd);
+            }
+        }
+        out.write("\n\n");
+    }
+
+    /**
+     * Write a namespace declaration to this writer. Note, that this method
+     * has no effect if there is no extra namespace write present.
+     *
+     * @param prefix  namespace prefix
+     * @throws IOException  if an I/O error occurs
+     */
+    public void writeNamespaceDeclaration(String prefix) throws IOException {
+        if (nsWriter != null && !usedNamespaces.contains(prefix)) {
+            usedNamespaces.add(prefix);
+            nsWriter.write("<'");
+            nsWriter.write(prefix);
+            nsWriter.write("'='");
+            nsWriter.write(escape(nsMapping.getNamespaceURI(prefix)));
+            nsWriter.write("'>\n");
+        }
+    }
+
+    /**
+     * Flushes all pending write operations and Closes this writer. please note,
+     * that the underlying writer remains open.
+     *
+     * @throws IOException if an I/O error occurs
+     */
+    public void close() throws IOException {
+        if (nsWriter != null) {
+            nsWriter.write("\n");
+            out.close();
+            nsWriter.write(((StringWriter) out).getBuffer().toString());
+            out = nsWriter;
+            nsWriter = null;
+        }
+        out.flush();
+        out = null;
+    }
+
+    //------------------------------------------------------------< private >---
+    /**
+     * write name
+     * @param ntd node type definition
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeName(NodeTypeDefinition ntd) throws IOException {
+        out.write(Lexer.BEGIN_NODE_TYPE_NAME);
+        writeJcrName(ntd.getName());
+        out.write(Lexer.END_NODE_TYPE_NAME);
+    }
+
+    /**
+     * Write the super type definitions.
+     * 
+     * @param ntd node type definition
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeSupertypes(NodeTypeDefinition ntd) throws IOException {
+        // get ordered list of supertypes, omitting nt:base
+        TreeSet<String> supertypes = new TreeSet<String>();
+        for (String name : ntd.getDeclaredSupertypeNames()) {
+            if (!name.equals(JcrConstants.NT_BASE)) {
+                supertypes.add(name);
+            }
+        }
+        if (!supertypes.isEmpty()) {
+            String delim = " " + Lexer.EXTENDS + " ";
+            for (String name : supertypes) {
+                out.write(delim);
+                writeJcrName(name);
+                delim = ", ";
+            }
+        }
+    }
+
+    /**
+     * Write the options
+     * 
+     * @param ntd node type definition
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeOptions(NodeTypeDefinition ntd) throws IOException {
+        List<String> options = new LinkedList<String>();
+        if (ntd.isAbstract()) {
+            options.add(Lexer.ABSTRACT[0]);
+        }
+        if (ntd.hasOrderableChildNodes()) {
+            options.add(Lexer.ORDERABLE[0]);
+        }
+        if (ntd.isMixin()) {
+            options.add(Lexer.MIXIN[0]);
+        }
+        if (!ntd.isQueryable()) {
+            options.add(Lexer.NOQUERY[0]);
+        }
+        String pin = ntd.getPrimaryItemName();
+        if (pin != null) {
+            options.add(Lexer.PRIMARYITEM[0]);
+        }
+        for (int i = 0; i < options.size(); i++) {
+            if (i == 0) {
+                out.write("\n" + INDENT);
+            } else {
+                out.write(" ");
+            }
+            out.write(options.get(i));
+        }
+
+        if (pin != null) {
+            out.write(" ");
+            writeJcrName(pin);            
+        }
+    }
+
+    /**
+     * Write a property definition
+     * 
+     * @param pd property definition
+     * @throws IOException if an I/O error occurs
+     */
+    private void writePropDef(PropertyDefinition pd) throws IOException {
+        out.write("\n" + INDENT + Lexer.PROPERTY_DEFINITION + " ");
+
+        writeJcrName(pd.getName());
+        out.write(" ");
+        out.write(Lexer.BEGIN_TYPE);
+        out.write(PropertyType.nameFromValue(pd.getRequiredType()).toLowerCase());
+        out.write(Lexer.END_TYPE);
+        writeDefaultValues(pd.getDefaultValues());
+        if (pd.isMandatory()) {
+            out.write(" ");
+            out.write(Lexer.MANDATORY[0]);
+        }
+        if (pd.isAutoCreated()) {
+            out.write(" ");
+            out.write(Lexer.AUTOCREATED[0]);
+        }
+        if (pd.isProtected()) {
+            out.write(" ");
+            out.write(Lexer.PROTECTED[0]);
+        }
+        if (pd.isMultiple()) {
+            out.write(" ");
+            out.write(Lexer.MULTIPLE[0]);
+        }
+        if (pd.getOnParentVersion() != OnParentVersionAction.COPY) {
+            out.write(" ");
+            out.write(OnParentVersionAction.nameFromValue(pd.getOnParentVersion()).toLowerCase());
+        }
+        if (!pd.isFullTextSearchable()) {
+            out.write(" ");
+            out.write(Lexer.NOFULLTEXT[0]);
+        }
+        if (!pd.isQueryOrderable()) {
+            out.write(" ");
+            out.write(Lexer.NOQUERYORDER[0]);
+        }
+        String[] qops = pd.getAvailableQueryOperators();
+        if (qops != null && qops.length > 0) {
+            List<String> opts = new ArrayList<String>(Arrays.asList(qops));
+            List<String> defaultOps = Arrays.asList(Operator.getAllQueryOperators());
+            if (!opts.containsAll(defaultOps)) {
+                out.write(" ");
+                out.write(Lexer.QUERYOPS[0]);
+                out.write(" '");
+                String delim = "";
+                for (String opt: opts) {
+                    out.write(delim);
+                    delim= ", ";
+                    if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_EQUAL_TO)) {
+                        out.write(Lexer.QUEROPS_EQUAL);
+                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_NOT_EQUAL_TO))
{
+                        out.write(Lexer.QUEROPS_NOTEQUAL);
+                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_GREATER_THAN))
{
+                        out.write(Lexer.QUEROPS_GREATERTHAN);
+                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_GREATER_THAN_OR_EQUAL_TO))
{
+                        out.write(Lexer.QUEROPS_GREATERTHANOREQUAL);
+                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_LESS_THAN))
{
+                        out.write(Lexer.QUEROPS_LESSTHAN);
+                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_LESS_THAN_OR_EQUAL_TO))
{
+                        out.write(Lexer.QUEROPS_LESSTHANOREQUAL);
+                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_LIKE)) {
+                        out.write(Lexer.QUEROPS_LIKE);
+                    }
+                }
+                out.write("'");
+            }
+        }
+        writeValueConstraints(pd.getValueConstraints(), pd.getRequiredType());
+    }
+
+    /**
+     * Write default values
+     * 
+     * @param dva default value
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeDefaultValues(Value[] dva) throws IOException {
+        if (dva != null && dva.length > 0) {
+            String delim = " = '";
+            for (Value value : dva) {
+                out.write(delim);
+                try {
+                    out.write(escape(value.getString()));
+                } catch (RepositoryException e) {
+                    out.write(escape(value.toString()));
+                }
+                out.write("'");
+                delim = ", '";
+            }
+        }
+    }
+
+    /**
+     * Write the value constraints
+     *
+     * @param constraints the value constraints
+     * @param type value type
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeValueConstraints(String[] constraints, int type) throws IOException
{
+        if (constraints != null && constraints.length > 0) {
+            out.write(" ");
+            out.write(Lexer.CONSTRAINT);
+            out.write(" '");
+            out.write(escape(constraints[0]));
+            out.write("'");
+            for (int i = 1; i < constraints.length; i++) {
+                out.write(", '");
+                out.write(escape(constraints[i]));
+                out.write("'");
+            }
+        }
+    }
+
+    /**
+     * Write a child node definition
+     *
+     * @param nd node definition
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeNodeDef(NodeDefinition nd) throws IOException {
+        out.write("\n" + INDENT + Lexer.CHILD_NODE_DEFINITION + " ");
+
+        writeJcrName(nd.getName());
+        writeRequiredTypes(nd.getRequiredPrimaryTypeNames());
+        writeDefaultType(nd.getDefaultPrimaryTypeName());
+        if (nd.isMandatory()) {
+            out.write(" ");
+            out.write(Lexer.MANDATORY[0]);
+        }
+        if (nd.isAutoCreated()) {
+            out.write(" ");
+            out.write(Lexer.AUTOCREATED[0]);
+        }
+        if (nd.isProtected()) {
+            out.write(" ");
+            out.write(Lexer.PROTECTED[0]);
+        }
+        if (nd.allowsSameNameSiblings()) {
+            out.write(" ");
+            out.write(Lexer.MULTIPLE[0]);
+        }
+        if (nd.getOnParentVersion() != OnParentVersionAction.COPY) {
+            out.write(" ");
+            out.write(OnParentVersionAction.nameFromValue(nd.getOnParentVersion()).toLowerCase());
+        }
+    }
+    
+    /**
+     * write required types
+     * @param reqTypes required type names
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeRequiredTypes(String[] reqTypes) throws IOException {
+        if (reqTypes != null && reqTypes.length > 0) {
+            String delim = " " + Lexer.BEGIN_TYPE;
+            for (String reqType : reqTypes) {
+                out.write(delim);
+                writeJcrName(reqType);
+                delim = ", ";
+            }
+            out.write(Lexer.END_TYPE);
+        }
+    }
+
+    /**
+     * write default types
+     * @param defType default type name
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeDefaultType(String defType) throws IOException {
+        if (defType != null && !defType.equals("*")) {
+            out.write(" = ");
+            writeJcrName(defType);
+        }
+    }
+
+    /**
+     * Write the name and updated the namespace declarations if needed.
+     * 
+     * @param name name to write
+     * @throws IOException if an I/O error occurs
+     */
+    private void writeJcrName(String name) throws IOException {
+        if (name == null) {
+            return;
+        }
+
+        String prefix = Text.getNamespacePrefix(name);
+        if (!prefix.equals(NamespaceRegistry.PREFIX_EMPTY)) {
+            // update namespace declaration
+            writeNamespaceDeclaration(prefix);
+            prefix += ":";
+        }
+
+        String localName = Text.getLocalName(name);
+        String encLocalName = (ANY.equals(localName)) ? ANY : ISO9075.encode(Text.getLocalName(name));
+        String resolvedName = prefix + encLocalName;
+
+        // check for '-' and '+'
+        boolean quotesNeeded = (name.indexOf('-') >= 0 || name.indexOf('+') >= 0);
+        if (quotesNeeded) {
+            out.write("'");
+            out.write(resolvedName);
+            out.write("'");
+        } else {
+            out.write(resolvedName);
+        }
+    }
+
+    /**
+     * escape
+     * @param s string
+     * @return the escaped string
+     */
+    private String escape(String s) {
+        StringBuffer sb = new StringBuffer(s);
+        for (int i = 0; i < sb.length(); i++) {
+            if (sb.charAt(i) == '\\') {
+                sb.insert(i, '\\');
+                i++;
+            } else if (sb.charAt(i) == '\'') {
+                sb.insert(i, '\'');
+                i++;
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Map namespace prefixes such as present in a qualified JCR name to
+     * the corresponding namespace URI.
+     */
+    public interface NamespaceMapping {
+
+        String getNamespaceURI(String prefix);
+    }
+
+    /**
+     * Default implementation using <code>Session</code> to determine
+     * the namespace URI.
+     */
+    private static class DefaultNamespaceMapping implements NamespaceMapping {
+
+        private final Session session;
+
+        private DefaultNamespaceMapping(Session session) {
+            this.session = session;
+        }
+
+        public String getNamespaceURI(String prefix) {
+            try {
+                return session.getNamespaceURI(prefix);
+            } catch (RepositoryException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/cnd/CompactNodeTypeDefWriter.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java?rev=1155283&r1=1155282&r2=1155283&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java
(original)
+++ jackrabbit/trunk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/compact/CompactNodeTypeDefWriter.java
Tue Aug  9 09:33:30 2011
@@ -16,45 +16,21 @@
  */
 package org.apache.jackrabbit.spi.commons.nodetype.compact;
 
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.jcr.NamespaceException;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.nodetype.NodeTypeDefinition;
-import javax.jcr.query.qom.QueryObjectModelConstants;
-import javax.jcr.version.OnParentVersionAction;
-
-import org.apache.jackrabbit.commons.cnd.Lexer;
-import org.apache.jackrabbit.commons.query.qom.Operator;
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.QNodeTypeDefinition;
-import org.apache.jackrabbit.spi.QPropertyDefinition;
-import org.apache.jackrabbit.spi.QValue;
-import org.apache.jackrabbit.spi.QValueConstraint;
-import org.apache.jackrabbit.spi.commons.QNodeTypeDefinitionImpl;
 import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
-import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver;
 import org.apache.jackrabbit.spi.commons.namespace.SessionNamespaceResolver;
-import org.apache.jackrabbit.spi.commons.nodetype.InvalidConstraintException;
-import org.apache.jackrabbit.spi.commons.nodetype.constraint.ValueConstraint;
+import org.apache.jackrabbit.spi.commons.nodetype.NodeTypeDefinitionImpl;
 import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl;
-import org.apache.jackrabbit.spi.commons.value.ValueFormat;
-import org.apache.jackrabbit.util.ISO9075;
+import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeTypeDefinition;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Collection;
 
 /**
  * Prints node type defs in a compact notation
@@ -68,17 +44,7 @@ import org.apache.jackrabbit.util.ISO907
  *   + ex:node (ex:reqType1, ex:reqType2) = ex:defaultType
  *     mandatory autocreated protected multiple VERSION
  */
-public class CompactNodeTypeDefWriter {
-
-    /**
-     * the indention string
-     */
-    private static final String INDENT = "  ";
-
-    /**
-     * the current namespace resolver
-     */
-    private final NamespaceResolver resolver;
+public class CompactNodeTypeDefWriter extends org.apache.jackrabbit.commons.cnd.CompactNodeTypeDefWriter
{
 
     /**
      * the current name/path resolver
@@ -86,21 +52,6 @@ public class CompactNodeTypeDefWriter {
     private final NamePathResolver npResolver;
 
     /**
-     * the underlying writer
-     */
-    private Writer out;
-
-    /**
-     * special writer used for namespaces
-     */
-    private Writer nsWriter;
-
-    /**
-     * namespaces(prefixes) that are used
-     */
-    private final Set<String> usedNamespaces = new HashSet<String>();
-
-    /**
      * Creates a new nodetype writer based on a session
      *
      * @param out the underlaying writer
@@ -147,18 +98,11 @@ public class CompactNodeTypeDefWriter {
      *                  written to the writer
      */
     public CompactNodeTypeDefWriter(Writer out,
-                                    NamespaceResolver r,
+                                    final NamespaceResolver r,
                                     NamePathResolver npResolver,
                                     boolean includeNS) {
-        this.resolver = r;
+        super(out, createNsMapping(r), includeNS);
         this.npResolver = npResolver;
-        if (includeNS) {
-            this.out = new StringWriter();
-            this.nsWriter = out;
-        } else {
-            this.out = out;
-            this.nsWriter = null;
-        }
     }
 
     /**
@@ -190,12 +134,8 @@ public class CompactNodeTypeDefWriter {
      * @throws IOException if an I/O error occurs
      */
     public void write(QNodeTypeDefinition ntd) throws IOException {
-        writeName(ntd);
-        writeSupertypes(ntd);
-        writeOptions(ntd);
-        writePropDefs(ntd);
-        writeNodeDefs(ntd);
-        out.write("\n\n");
+        NodeTypeDefinition def = new NodeTypeDefinitionImpl(ntd, npResolver, new ValueFactoryQImpl(QValueFactoryImpl.getInstance(),
npResolver));
+        super.write(def);
     }
 
     /**
@@ -210,401 +150,15 @@ public class CompactNodeTypeDefWriter {
         }
     }
 
-    /**
-     * Write one NodeTypeDefinition to this writer
-     *
-     * @param nt node type definition
-     * @throws IOException if an I/O error occurs
-     */
-    public void write(NodeTypeDefinition nt) throws IOException {
-        try {
-            write(new QNodeTypeDefinitionImpl(nt, npResolver, QValueFactoryImpl.getInstance()));
-        } catch (RepositoryException e) {
-            throw new IOException("Error during internal conversion of nodetype definition:"
+ e.toString());
-        }
-    }
-
-    /**
-     * Write a namespace declaration to this writer. This method has no effect if the
-     * writer does not include namespaces.
-     *
-     * @param prefix  namespace prefix
-     * @throws NamespaceException  if no namespace is registered for the given prefix
-     * @throws IOException  if an I/O error occurs
-     */
-    public void writeNamespaceDelclaration(String prefix) throws NamespaceException, IOException
{
-        if (!usedNamespaces.contains(prefix)) {
-            usedNamespaces.add(prefix);
-            nsWriter.write("<'");
-            nsWriter.write(prefix);
-            nsWriter.write("'='");
-            nsWriter.write(escape(resolver.getURI(prefix)));
-            nsWriter.write("'>\n");
-        }
-    }
-
-    /**
-     * Flushes all pending write operations and Closes this writer. please note,
-     * that the underlying writer remains open.
-     *
-     * @throws IOException if an I/O error occurs
-     */
-    public void close() throws IOException {
-        if (nsWriter != null) {
-            nsWriter.write("\n");
-            out.close();
-            nsWriter.write(((StringWriter) out).getBuffer().toString());
-            out = nsWriter;
-            nsWriter = null;
-        }
-        out.flush();
-        out = null;
-    }
-
-    /**
-     * write name
-     * @param ntd node type definition
-     * @throws IOException if an I/O error occurs
-     */
-    private void writeName(QNodeTypeDefinition ntd) throws IOException {
-        out.write("[");
-        out.write(resolve(ntd.getName()));
-        out.write("]");
-    }
-
-    /**
-     * write supertypes
-     * @param ntd node type definition
-     * @throws IOException if an I/O error occurs
-     */
-    private void writeSupertypes(QNodeTypeDefinition ntd) throws IOException {
-        // get ordered list of supertypes, omitting nt:Base
-        TreeSet<Name> supertypes = new TreeSet<Name>();
-        for (Name name : ntd.getSupertypes()) {
-            if (!name.equals(NameConstants.NT_BASE)) {
-                supertypes.add(name);
-            }
-        }
-        if (!supertypes.isEmpty()) {
-            String delim = " > ";
-            for (Name name : supertypes) {
-                out.write(delim);
-                out.write(resolve(name));
-                delim = ", ";
-            }
-        }
-    }
-
-    /**
-     * write options
-     * @param ntd node type definition
-     * @throws IOException if an I/O error occurs
-     */
-    private void writeOptions(QNodeTypeDefinition ntd) throws IOException {
-        List<String> options = new LinkedList<String>();
-        if (ntd.isAbstract()) {
-            options.add(Lexer.ABSTRACT[0]);
-        }
-        if (ntd.hasOrderableChildNodes()) {
-            options.add(Lexer.ORDERABLE[0]);
-        }
-        if (ntd.isMixin()) {
-            options.add(Lexer.MIXIN[0]);
-        }
-        if (!ntd.isQueryable()) {
-            options.add(Lexer.NOQUERY[0]);
-        }
-        if (ntd.getPrimaryItemName() != null) {
-            options.add(Lexer.PRIMARYITEM[0]);
-            options.add(resolve(ntd.getPrimaryItemName()));
-        }
-        for (int i = 0; i < options.size(); i++) {
-            if (i == 0) {
-                out.write("\n" + INDENT);
-            } else {
-                out.write(" ");
-            }
-            out.write(options.get(i));
-        }
-    }
-
-    /**
-     * write prop defs
-     * @param ntd node type definition
-     * @throws IOException if an I/O error occurs
-     */
-    private void writePropDefs(QNodeTypeDefinition ntd) throws IOException {
-        for (QPropertyDefinition pd : ntd.getPropertyDefs()) {
-            writePropDef(pd);
-        }
-    }
-
-    /**
-     * write node defs
-     * @param ntd node type definition
-     * @throws IOException if an I/O error occurs
-     */
-    private void writeNodeDefs(QNodeTypeDefinition ntd) throws IOException {
-        for (QNodeDefinition nd : ntd.getChildNodeDefs()) {
-            writeNodeDef(nd);
-        }
-    }
-
-    /**
-     * write prop def
-     * @param pd property definition
-     * @throws IOException if an I/O error occurs
-     */
-    private void writePropDef(QPropertyDefinition pd) throws IOException {
-        out.write("\n" + INDENT + "- ");
-
-        Name name = pd.getName();
-        if (name.equals(NameConstants.ANY_NAME)) {
-            out.write('*');
-        } else {
-            writeItemDefName(name);
-        }
-
-        out.write(" (");
-        out.write(PropertyType.nameFromValue(pd.getRequiredType()).toLowerCase());
-        out.write(")");
-        writeDefaultValues(pd.getDefaultValues());
-        if (pd.isMandatory()) {
-            out.write(" mandatory");
-        }
-        if (pd.isAutoCreated()) {
-            out.write(" autocreated");
-        }
-        if (pd.isProtected()) {
-            out.write(" protected");
-        }
-        if (pd.isMultiple()) {
-            out.write(" multiple");
-        }
-        if (pd.getOnParentVersion() != OnParentVersionAction.COPY) {
-            out.write(" ");
-            out.write(OnParentVersionAction.nameFromValue(pd.getOnParentVersion()).toLowerCase());
-        }
-        if (!pd.isFullTextSearchable()) {
-            out.write(" nofulltext");
-        }
-        if (!pd.isQueryOrderable()) {
-            out.write(" noqueryorder");
-        }
-        String[] qops = pd.getAvailableQueryOperators();
-        if (qops != null && qops.length > 0) {
-            List<String> opts = new ArrayList<String>(Arrays.asList(qops));
-            List<String> defaultOps = Arrays.asList(Operator.getAllQueryOperators());
-            if (!opts.containsAll(defaultOps)) {
-                out.write(" queryops '");
-                String delim = "";
-                for (String opt: opts) {
-                    out.write(delim);
-                    delim= ", ";
-                    if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_EQUAL_TO)) {
-                        out.write(Lexer.QUEROPS_EQUAL);
-                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_NOT_EQUAL_TO))
{
-                        out.write(Lexer.QUEROPS_NOTEQUAL);
-                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_GREATER_THAN))
{
-                        out.write(Lexer.QUEROPS_GREATERTHAN);
-                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_GREATER_THAN_OR_EQUAL_TO))
{
-                        out.write(Lexer.QUEROPS_GREATERTHANOREQUAL);
-                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_LESS_THAN))
{
-                        out.write(Lexer.QUEROPS_LESSTHAN);
-                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_LESS_THAN_OR_EQUAL_TO))
{
-                        out.write(Lexer.QUEROPS_LESSTHANOREQUAL);
-                    } else if (opt.equals(QueryObjectModelConstants.JCR_OPERATOR_LIKE)) {
-                        out.write(Lexer.QUEROPS_LIKE);
-                    }
-                }
-                out.write("'");
-            }
-        }
-        writeValueConstraints(pd.getValueConstraints(), pd.getRequiredType());
-    }
-
-    /**
-     * write default values
-     * @param dva default value
-     * @throws IOException if an I/O error occurs
-     */
-    private void writeDefaultValues(QValue[] dva) throws IOException {
-        if (dva != null && dva.length > 0) {
-            String delim = " = '";
-            for (QValue value : dva) {
-                out.write(delim);
+    private static NamespaceMapping createNsMapping(final NamespaceResolver namespaceResolver)
{
+        return new org.apache.jackrabbit.commons.cnd.CompactNodeTypeDefWriter.NamespaceMapping()
{
+            public String getNamespaceURI(String prefix) {
                 try {
-                    String str = ValueFormat.getJCRString(value, npResolver);
-                    out.write(escape(str));
-                } catch (RepositoryException e) {
-                    out.write(escape(value.toString()));
+                    return namespaceResolver.getURI(prefix);
+                } catch (NamespaceException e) {
+                    throw new RuntimeException(e);
                 }
-                out.write("'");
-                delim = ", '";
-            }
-        }
-    }
-
-    /**
-     * write value constraints
-     * @param vca value constraint
-     * @param type value type
-     * @throws IOException if an I/O error occurs
-     */
-    private void writeValueConstraints(QValueConstraint[] vca, int type) throws IOException
{
-        if (vca != null && vca.length > 0) {
-            String vc = convertConstraint(vca[0], type);
-            out.write(" < '");
-            out.write(escape(vc));
-            out.write("'");
-            for (int i = 1; i < vca.length; i++) {
-                vc = convertConstraint(vca[i], type);
-                out.write(", '");
-                out.write(escape(vc));
-                out.write("'");
             }
-        }
-    }
-
-    /**
-     * Converts the constraint to a jcr value
-     * @param vc value constraint string
-     * @param type value type
-     * @return converted value
-     */
-    private String convertConstraint(QValueConstraint vc, int type) {
-        try {
-            ValueConstraint c = ValueConstraint.create(type, vc.getString());
-            return c.getDefinition(npResolver);
-        } catch (InvalidConstraintException e) {
-            // ignore -> return unconverted constraint
-            return vc.getString();
-        }
-    }
-
-    /**
-     * write node def
-     *
-     * @param nd node definition
-     * @throws IOException if an I/O error occurs
-     */
-    private void writeNodeDef(QNodeDefinition nd) throws IOException {
-        out.write("\n" + INDENT + "+ ");
-
-        Name name = nd.getName();
-        if (name.equals(NameConstants.ANY_NAME)) {
-            out.write('*');
-        } else {
-            writeItemDefName(name);
-        }
-        writeRequiredTypes(nd.getRequiredPrimaryTypes());
-        writeDefaultType(nd.getDefaultPrimaryType());
-        if (nd.isMandatory()) {
-            out.write(" mandatory");
-        }
-        if (nd.isAutoCreated()) {
-            out.write(" autocreated");
-        }
-        if (nd.isProtected()) {
-            out.write(" protected");
-        }
-        if (nd.allowsSameNameSiblings()) {
-            out.write(" multiple");
-        }
-        if (nd.getOnParentVersion() != OnParentVersionAction.COPY) {
-            out.write(" ");
-            out.write(OnParentVersionAction.nameFromValue(nd.getOnParentVersion()).toLowerCase());
-        }
-    }
-
-    /**
-     * Write item def name
-     * @param name name
-     * @throws IOException if an I/O error occurs
-     */
-    private void writeItemDefName(Name name) throws IOException {
-        out.write(resolve(name));
-    }
-    /**
-     * write required types
-     * @param reqTypes required type names
-     * @throws IOException if an I/O error occurs
-     */
-    private void writeRequiredTypes(Name[] reqTypes) throws IOException {
-        if (reqTypes != null && reqTypes.length > 0) {
-            String delim = " (";
-            for (Name reqType : reqTypes) {
-                out.write(delim);
-                out.write(resolve(reqType));
-                delim = ", ";
-            }
-            out.write(")");
-        }
-    }
-
-    /**
-     * write default types
-     * @param defType default type name
-     * @throws IOException if an I/O error occurs
-     */
-    private void writeDefaultType(Name defType) throws IOException {
-        if (defType != null && !defType.getLocalName().equals("*")) {
-            out.write(" = ");
-            out.write(resolve(defType));
-        }
-    }
-
-    /**
-     * resolve
-     * @param name name to resolve
-     * @return the resolved name
-     * @throws IOException if an I/O error occurs
-     */
-    private String resolve(Name name) throws IOException {
-        if (name == null) {
-            return "";
-        }
-        try {
-            String prefix = resolver.getPrefix(name.getNamespaceURI());
-            if (prefix != null && !prefix.equals(Name.NS_EMPTY_PREFIX)) {
-                // check for writing namespaces
-                if (nsWriter != null) {
-                    writeNamespaceDelclaration(prefix);
-                }
-                prefix += ":";
-            }
-
-            String encLocalName = ISO9075.encode(name.getLocalName());
-            String resolvedName = prefix + encLocalName;
-
-            // check for '-' and '+'
-            if (resolvedName.indexOf('-') >= 0 || resolvedName.indexOf('+') >= 0) {
-                return "'" + resolvedName + "'";
-            } else {
-                return resolvedName;
-            }
-
-        } catch (NamespaceException e) {
-            return name.toString();
-        }
-    }
-
-    /**
-     * escape
-     * @param s string
-     * @return the escaped string
-     */
-    private String escape(String s) {
-        StringBuffer sb = new StringBuffer(s);
-        for (int i = 0; i < sb.length(); i++) {
-            if (sb.charAt(i) == '\\') {
-                sb.insert(i, '\\');
-                i++;
-            } else if (sb.charAt(i) == '\'') {
-                sb.insert(i, '\'');
-                i++;
-            }
-        }
-        return sb.toString();
+        };
     }
 }



Mime
View raw message