blob: d0661ba974c58e36ae39dd267a22aced8201af50 [file] [log] [blame]
/*
* 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.vault.fs.impl.io;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import org.apache.commons.io.output.CloseShieldOutputStream;
import org.apache.jackrabbit.vault.fs.api.Aggregate;
import org.apache.jackrabbit.vault.fs.api.SerializationType;
import org.apache.jackrabbit.vault.fs.io.Serializer;
import org.apache.jackrabbit.vault.util.JcrConstants;
/**
* {@code DocViewSerializer}...
*
*/
public class CNDSerializer implements Serializer {
/**
* the indention string
*/
private static final String INDENT = " ";
/**
* the export context
*/
private final Aggregate aggregate;
/**
* Creates a new doc view serializer
* @param aggregate the export context
*/
public CNDSerializer(Aggregate aggregate) {
this.aggregate = aggregate;
}
/**
* {@inheritDoc}
*/
public void writeContent(OutputStream out) throws IOException, RepositoryException {
try (Writer w = new OutputStreamWriter(new CloseShieldOutputStream(out), "utf-8")) {
for (String prefix: aggregate.getNamespacePrefixes()) {
w.write("<'");
w.write(prefix);
w.write("'='");
w.write(escape(aggregate.getNamespaceURI(prefix)));
w.write("'>\n");
}
w.write("\n");
writeNodeTypeDef(w, aggregate.getNode());
}
out.flush();
}
private void writeNodeTypeDef(Writer out, Node node) throws IOException, RepositoryException {
writeName(out, node);
writeSupertypes(out, node);
writeOptions(out, node);
writeDefs(out, node);
out.write("\n");
}
private void writeName(Writer out, Node node)
throws IOException, RepositoryException {
out.write("[");
out.write(node.getProperty(JcrConstants.JCR_NODETYPENAME).getString());
out.write("]");
}
private void writeSupertypes(Writer out, Node node) throws IOException, RepositoryException {
Value[] types = node.getProperty(JcrConstants.JCR_SUPERTYPES).getValues();
String delim = " > ";
for (Value s: types) {
out.write(delim);
out.write(s.getString());
delim = ", ";
}
}
private void writeOptions(Writer out, Node node) throws IOException, RepositoryException {
String delim = "\n " + INDENT;
if (node.getProperty(JcrConstants.JCR_HASORDERABLECHILDNODES).getBoolean()) {
out.write(delim);
out.write("orderable");
delim = " ";
}
if (node.getProperty(JcrConstants.JCR_ISMIXIN).getBoolean()) {
out.write(delim);
out.write("mixin");
}
}
private void writeDefs(Writer out, Node node) throws IOException, RepositoryException {
NodeIterator iter = node.getNodes();
String primary = null;
if (node.hasProperty(JcrConstants.JCR_PRIMARYITEMNAME)) {
primary = node.getProperty(JcrConstants.JCR_PRIMARYITEMNAME).getString();
}
while (iter.hasNext()) {
Node child = iter.nextNode();
if (child.getPrimaryNodeType().getName().equals(JcrConstants.NT_PROPERTYDEFINITION)) {
writePropDef(out, child, primary);
}
}
iter = node.getNodes();
while (iter.hasNext()) {
Node child = iter.nextNode();
if (child.getPrimaryNodeType().getName().equals(JcrConstants.NT_CHILDNODEDEFINITION)) {
writeNodeDef(out, child, primary);
}
}
}
private void writePropDef(Writer out, Node node, String primary) throws IOException, RepositoryException {
out.write("\n" + INDENT + "- ");
String name = "*";
if (node.hasProperty(JcrConstants.JCR_NAME)) {
name = node.getProperty(JcrConstants.JCR_NAME).getString();
}
out.write(name);
out.write(" (");
out.write(node.getProperty(JcrConstants.JCR_REQUIREDTYPE).getString().toLowerCase());
out.write(")");
if (node.hasProperty(JcrConstants.JCR_DEFAULTVALUES)) {
writeDefaultValues(out, node.getProperty(JcrConstants.JCR_DEFAULTVALUES).getValues());
}
if (primary != null && primary.equals(name)) {
out.write(" primary");
}
if (node.getProperty(JcrConstants.JCR_MANDATORY).getBoolean()) {
out.write(" mandatory");
}
if (node.getProperty(JcrConstants.JCR_AUTOCREATED).getBoolean()) {
out.write(" autocreated");
}
if (node.getProperty(JcrConstants.JCR_PROTECTED).getBoolean()) {
out.write(" protected");
}
if (node.getProperty(JcrConstants.JCR_MULTIPLE).getBoolean()) {
out.write(" multiple");
}
String opv = node.getProperty(JcrConstants.JCR_ONPARENTVERSION).getString().toLowerCase();
if (!opv.equals("copy")) {
out.write(" ");
out.write(opv);
}
if (node.hasProperty(JcrConstants.JCR_VALUECONSTRAINTS)) {
writeValueConstraints(out, node.getProperty(JcrConstants.JCR_VALUECONSTRAINTS).getValues());
}
}
private void writeDefaultValues(Writer out, Value[] dva) throws IOException, RepositoryException {
if (dva != null && dva.length > 0) {
String delim = " = '";
for (Value value : dva) {
out.write(delim);
out.write(escape(value.getString()));
out.write("'");
delim = ", '";
}
}
}
private void writeValueConstraints(Writer out, Value[] vca) throws IOException, RepositoryException {
String delim = "\n" + INDENT + " < ";
for (Value v: vca) {
out.write(delim);
out.write("'");
out.write(escape(v.getString()));
out.write("'");
delim = ", ";
}
}
private void writeNodeDef(Writer out, Node node, String primary) throws IOException, RepositoryException {
out.write("\n" + INDENT + "+ ");
String name = "*";
if (node.hasProperty(JcrConstants.JCR_NAME)) {
name = node.getProperty(JcrConstants.JCR_NAME).getString();
}
out.write(name);
writeRequiredTypes(out, node.getProperty(JcrConstants.JCR_REQUIREDPRIMARYTYPES).getValues());
if (node.hasProperty(JcrConstants.JCR_DEFAULTPRIMARYTYPE)) {
writeDefaultType(out, node.getProperty(JcrConstants.JCR_DEFAULTPRIMARYTYPE).getString());
}
if (primary != null && primary.equals(name)) {
out.write(" primary");
}
if (node.getProperty(JcrConstants.JCR_MANDATORY).getBoolean()) {
out.write(" mandatory");
}
if (node.getProperty(JcrConstants.JCR_AUTOCREATED).getBoolean()) {
out.write(" autocreated");
}
if (node.getProperty(JcrConstants.JCR_PROTECTED).getBoolean()) {
out.write(" protected");
}
if (node.getProperty(JcrConstants.JCR_SAMENAMESIBLINGS).getBoolean()) {
out.write(" multiple");
}
String opv = node.getProperty(JcrConstants.JCR_ONPARENTVERSION).getString().toLowerCase();
if (!opv.equals("copy")) {
out.write(" ");
out.write(opv);
}
}
private void writeRequiredTypes(Writer out, Value[] reqTypes) throws IOException, RepositoryException {
if (reqTypes.length > 0) {
String delim = " (";
for (Value value : reqTypes) {
out.write(delim);
out.write(value.getString());
delim = ", ";
}
out.write(")");
}
}
private void writeDefaultType(Writer out, String defType) throws IOException {
if (!defType.equals("*")) {
out.write(" = ");
out.write(defType);
}
}
/**
* escape
* @param s the string to escape
* @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();
}
/**
* {@inheritDoc}
*
* @return {@link SerializationType#CND}
*/
public SerializationType getType() {
return SerializationType.CND;
}
}