You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2013/08/10 07:53:54 UTC
svn commit: r1512568 [22/39] - in /jackrabbit/commons/filevault/trunk: ./
parent/ vault-cli/ vault-cli/src/ vault-cli/src/main/
vault-cli/src/main/appassembler/ vault-cli/src/main/assembly/
vault-cli/src/main/java/ vault-cli/src/main/java/org/ vault-cl...
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewProperty.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewProperty.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewProperty.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/DocViewProperty.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,369 @@
+/*
+ * 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.util;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFormatException;
+
+import org.apache.jackrabbit.util.XMLChar;
+import org.apache.jackrabbit.value.ValueHelper;
+
+/**
+ * Helper class that represents a (jcr) property in the document view format.
+ * It contains formatting and parsing methods for writing/reading enhanced
+ * docview properties.
+ *
+ * <code>prop:= [ "{" type "}" ] ( value | "[" [ value { "," value } ] "]" )</code>
+ */
+public class DocViewProperty {
+
+ /**
+ * name of the property
+ */
+ public final String name;
+
+ /**
+ * value(s) of the property. always contains at least one value if this is
+ * not a mv property.
+ */
+ public final String[] values;
+
+ /**
+ * indicates a MV property
+ */
+ public final boolean isMulti;
+
+ /**
+ * type of this property (can be undefined)
+ */
+ public final int type;
+
+ /**
+ * set of unambigous property names
+ */
+ private static final Set<String> UNAMBIGOUS = new HashSet<String>();
+ static {
+ UNAMBIGOUS.add("jcr:primaryType");
+ UNAMBIGOUS.add("jcr:mixinTypes");
+ }
+
+ /**
+ * Creates a new property.
+ * @param name name of the property
+ * @param values values.
+ * @param multi multiple flag
+ * @param type type of the property
+ * @throws IllegalArgumentException if single value property and not
+ * exactly 1 value is given.
+ */
+ public DocViewProperty(String name, String[] values, boolean multi, int type) {
+ this.name = name;
+ this.values = values;
+ isMulti = multi;
+ // validate type
+ if (type == PropertyType.UNDEFINED) {
+ if (name.equals("jcr:primaryType") || name.equals("jcr:mixinTypes")) {
+ type = PropertyType.NAME;
+ }
+ }
+ this.type = type;
+ if (!isMulti && values.length != 1) {
+ throw new IllegalArgumentException("Single value property needs exactly 1 value.");
+ }
+ }
+
+ /**
+ * Parses a enhanced docview property string and returns the property.
+ * @param name name of the property
+ * @param value (attribute) value
+ * @return a property
+ */
+ public static DocViewProperty parse(String name, String value) {
+ boolean isMulti = false;
+ int type = PropertyType.UNDEFINED;
+ int pos = 0;
+ char state = 'b';
+ List<String> vals = null;
+ StringBuffer tmp = new StringBuffer();
+ int unicode = 0;
+ int unicodePos = 0;
+ while (pos < value.length()) {
+ char c = value.charAt(pos++);
+ switch (state) {
+ case 'b': // begin (type or array or value)
+ if (c == '{') {
+ state = 't';
+ } else if (c == '[') {
+ isMulti = true;
+ state = 'v';
+ } else if (c == '\\') {
+ state = 'e';
+ } else {
+ tmp.append(c);
+ state = 'v';
+ }
+ break;
+ case 'a': // array (array or value)
+ if (c == '[') {
+ isMulti = true;
+ state = 'v';
+ } else if (c == '\\') {
+ state = 'e';
+ } else {
+ tmp.append(c);
+ state = 'v';
+ }
+ break;
+ case 't':
+ if (c == '}') {
+ type = PropertyType.valueFromName(tmp.toString());
+ tmp.setLength(0);
+ state = 'a';
+ } else {
+ tmp.append(c);
+ }
+ break;
+ case 'v': // value
+ if (c == '\\') {
+ state = 'e';
+ } else if (c == ',' && isMulti) {
+ if (vals == null) {
+ vals = new LinkedList<String>();
+ }
+ vals.add(tmp.toString());
+ tmp.setLength(0);
+ } else if (c == ']' && isMulti && pos == value.length()) {
+ if (tmp.length() > 0 || vals != null) {
+ if (vals == null) {
+ vals = new LinkedList<String>();
+ }
+ vals.add(tmp.toString());
+ tmp.setLength(0);
+ }
+ } else {
+ tmp.append(c);
+ }
+ break;
+ case 'e': // escaped
+ if (c == 'u') {
+ state = 'u';
+ unicode = 0;
+ unicodePos = 0;
+ } else {
+ state = 'v';
+ tmp.append(c);
+ }
+ break;
+ case 'u': // unicode escaped
+ unicode = (unicode << 4) + Character.digit(c, 16);
+ if (++unicodePos == 4) {
+ tmp.appendCodePoint(unicode);
+ state = 'v';
+ }
+ break;
+
+ }
+ }
+ String[] values;
+ if (isMulti) {
+ // add value if missing ']'
+ if (tmp.length() > 0) {
+ if (vals == null) {
+ vals = new LinkedList<String>();
+ }
+ vals.add(tmp.toString());
+ }
+ if (vals == null) {
+ values = Constants.EMPTY_STRING_ARRAY;
+ } else {
+ values = vals.toArray(new String[vals.size()]);
+ }
+ } else {
+ values = new String[]{tmp.toString()};
+ }
+ return new DocViewProperty(name, values, isMulti, type);
+ }
+ /**
+ * Formats the given jcr property to the enhanced docview syntax.
+ * @param prop the jcr property
+ * @return the formatted string
+ * @throws RepositoryException if a repository error occurs
+ */
+ public static String format(Property prop) throws RepositoryException {
+ return format(prop, false);
+ }
+
+ /**
+ * Formats the given jcr property to the enhanced docview syntax.
+ * @param prop the jcr property
+ * @param sort if <code>true</code> multivalue properties are sorted
+ * @return the formatted string
+ * @throws RepositoryException if a repository error occurs
+ */
+ public static String format(Property prop, boolean sort)
+ throws RepositoryException {
+ StringBuffer attrValue = new StringBuffer();
+ int type = prop.getType();
+ if (type == PropertyType.BINARY || isAmbiguous(prop)) {
+ attrValue.append("{");
+ attrValue.append(PropertyType.nameFromValue(prop.getType()));
+ attrValue.append("}");
+ }
+ // only write values for non binaries
+ if (prop.getType() != PropertyType.BINARY) {
+ if (prop.getDefinition().isMultiple()) {
+ attrValue.append('[');
+ Value[] values = prop.getValues();
+ if (sort) {
+ Arrays.sort(values, ValueComparator.getInstance());
+ }
+ for (int i = 0; i < values.length; i++) {
+ if (i > 0) {
+ attrValue.append(',');
+ }
+ String strValue = ValueHelper.serialize(values[i], false);
+ switch (prop.getType()) {
+ case PropertyType.STRING:
+ case PropertyType.NAME:
+ case PropertyType.PATH:
+ escape(attrValue, strValue, true);
+ break;
+ default:
+ attrValue.append(strValue);
+ }
+ }
+ attrValue.append(']');
+ } else {
+ String strValue = ValueHelper.serialize(prop.getValue(), false);
+ escape(attrValue, strValue, false);
+ }
+ }
+ return attrValue.toString();
+ }
+
+ /**
+ * Escapes the value
+ * @param buf buffer to append to
+ * @param value value to escape
+ * @param isMulti indicates multi value property
+ */
+ protected static void escape(StringBuffer buf, String value, boolean isMulti) {
+ for (int i=0; i<value.length(); i++) {
+ char c = value.charAt(i);
+ if (c == '\\') {
+ buf.append("\\\\");
+ } else if (c == ',' && isMulti) {
+ buf.append("\\,");
+ } else if (i == 0 && !isMulti && (c == '[' || c == '{')) {
+ buf.append('\\').append(c);
+ } else if ( XMLChar.isInvalid(c)) {
+ buf.append("\\u");
+ buf.append(Text.hexTable[(c >> 12) & 15]);
+ buf.append(Text.hexTable[(c >> 8) & 15]);
+ buf.append(Text.hexTable[(c >> 4) & 15]);
+ buf.append(Text.hexTable[c & 15]);
+ } else {
+ buf.append(c);
+ }
+ }
+ }
+
+ /**
+ * Checks if the type of the given property is ambiguous in respect to it's
+ * property definition. the current implementation just checks some well
+ * known properties.
+ *
+ * @param prop the property
+ * @return type
+ * @throws RepositoryException if a repository error occurs
+ */
+ public static boolean isAmbiguous(Property prop) throws RepositoryException {
+ return prop.getType() != PropertyType.STRING && !UNAMBIGOUS.contains(prop.getName());
+ }
+
+ /**
+ * Sets this property on the given node
+ *
+ * @param node the node
+ * @return <code>true</code> if the value was modified.
+ * @throws RepositoryException if a repository error occurs
+ */
+ public boolean apply(Node node) throws RepositoryException {
+ Property prop = node.hasProperty(name) ? node.getProperty(name) : null;
+ // check if multiple flags are equal
+ if (prop != null && isMulti != prop.getDefinition().isMultiple()) {
+ prop.remove();
+ prop = null;
+ }
+ if (prop != null) {
+ int propType = prop.getType();
+ if (propType != type && (propType != PropertyType.STRING || type != PropertyType.UNDEFINED)) {
+ // never compare if types differ
+ prop = null;
+ }
+ }
+ if (isMulti) {
+ Value[] vs = prop == null ? null : prop.getValues();
+ if (vs != null && vs.length == values.length) {
+ // quick check all values
+ boolean modified = false;
+ for (int i=0; i<vs.length; i++) {
+ if (!vs[i].getString().equals(values[i])) {
+ modified = true;
+ }
+ }
+ if (!modified) {
+ return false;
+ }
+ }
+ if (type == PropertyType.UNDEFINED) {
+ node.setProperty(name, values);
+ } else {
+ node.setProperty(name, values, type);
+ }
+ // assume modified
+ return true;
+ } else {
+ Value v = prop == null ? null : prop.getValue();
+ if (v == null || !v.getString().equals(values[0])) {
+ try {
+ if (type == PropertyType.UNDEFINED) {
+ node.setProperty(name, values[0]);
+ } else {
+ node.setProperty(name, values[0], type);
+ }
+ } catch (ValueFormatException e) {
+ // forcing string
+ node.setProperty(name, values[0], PropertyType.STRING);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/FileInputSource.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/FileInputSource.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/FileInputSource.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/FileInputSource.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,106 @@
+/*
+ * 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.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.vault.fs.api.VaultInputSource;
+
+/**
+ * Implements a input source that is based on a {@link File}. The path of the
+ * file is used as systemId.
+ * <p/>
+ * Currently only {@link #getByteStream()} is implemented.
+ *
+ */
+public class FileInputSource extends VaultInputSource {
+
+ /**
+ * the file
+ */
+ private final File file;
+
+ /**
+ * possible line feed
+ */
+ private byte[] lineSeparator;
+
+ /**
+ * Creates a new input source that is based on a file.
+ * @param file the file.
+ */
+ public FileInputSource(File file) {
+ super(file.getPath());
+ this.file = file;
+ }
+
+ /**
+ * Sets the linefeed to use. If this is not <code>null</code> the output
+ * stream of the file is wrapped by a {@link LineInputStream} with that
+ * given line feed
+ * @param lineSeparator the linefeed for text
+ */
+ public void setLineSeparator(byte[] lineSeparator) {
+ this.lineSeparator = lineSeparator;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @return a {@link FileInputStream} on the internal file.
+ */
+ public InputStream getByteStream() {
+ try {
+ if (lineSeparator != null) {
+ return new LineInputStream(new FileInputStream(file), lineSeparator);
+ } else {
+ return FileUtils.openInputStream(file);
+ }
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the content length of the underlying file.
+ * @return the content length of the underlying file.
+ */
+ public long getContentLength() {
+ return file.length();
+ }
+
+ /**
+ * Returns the last modified date of the underlying file.
+ * @return the last modified date of the underlying file.
+ */
+ public long getLastModified() {
+ return file.lastModified();
+ }
+
+ /**
+ * deletes the underlying file
+ */
+ public void discard() {
+ file.delete();
+ file.deleteOnExit();
+ }
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/HtmlProgressListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/HtmlProgressListener.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/HtmlProgressListener.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/HtmlProgressListener.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,99 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.jackrabbit.vault.fs.api.ProgressTrackerListener;
+
+/**
+ * <code>HtmlProgrressTrackerListener</code>...
+ *
+ */
+public class HtmlProgressListener implements ProgressTrackerListener {
+
+ private final Writer out;
+
+ private boolean noScrollTo;
+
+ private long scrollDelay = 1000;
+
+ private long lastScrolled = 0;
+
+ public HtmlProgressListener(Writer out) {
+ this.out = out;
+ }
+
+ public boolean isNoScrollTo() {
+ return noScrollTo;
+ }
+
+ public HtmlProgressListener setNoScrollTo(boolean noScrollTo) {
+ this.noScrollTo = noScrollTo;
+ return this;
+ }
+
+ public long getScrollDelay() {
+ return scrollDelay;
+ }
+
+ public HtmlProgressListener setScrollDelay(long scrollDelay) {
+ this.scrollDelay = scrollDelay;
+ return this;
+ }
+
+ public void onError(Mode mode, String path, Exception e) {
+ print(mode, "E", path, e.toString());
+ }
+
+ public void onMessage(Mode mode, String action, String path) {
+ print(mode, action, path, null);
+ }
+
+ private void print(Mode mode, String action, String path, String msg) {
+ try {
+ out.write("<span class=\"");
+ out.write(action);
+ out.write("\">");
+ out.write("<b>");
+ out.write(action);
+ out.write("</b> ");
+ out.write(path);
+ if (msg != null) {
+ out.write(" (");
+ out.write(msg);
+ out.write(")");
+ }
+ out.write("</span><br>\r\n");
+ if (!noScrollTo) {
+ long now = System.currentTimeMillis();
+ if (now > lastScrolled + scrollDelay) {
+ lastScrolled = now;
+ out.write("<script>\r\n");
+ out.write("window.scrollTo(0, 1000000);\r\n");
+ out.write("</script>\r\n");
+ }
+ }
+ out.flush();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/ItemNameComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/ItemNameComparator.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/ItemNameComparator.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/ItemNameComparator.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,50 @@
+/*
+ * 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.util;
+
+import java.util.Comparator;
+
+import javax.jcr.Item;
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>ItemNameComparator</code>...
+ */
+public class ItemNameComparator implements Comparator<Item> {
+
+ public static final ItemNameComparator INSTANCE = new ItemNameComparator();
+
+ public int compare(Item o1, Item o2) {
+ try {
+ // sort namespaced first
+ String n1 = o1.getName().toLowerCase();
+ String n2 = o2.getName().toLowerCase();
+ int i1 = n1.indexOf(':');
+ int i2 = n2.indexOf(':');
+ if (i1 >=0 && i2 < 0) {
+ return -1;
+ } else if (i1 < 0 && i2 >=0) {
+ return 1;
+ } else {
+ return n1.compareTo(n2);
+ }
+ } catch (RepositoryException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/JcrConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/JcrConstants.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/JcrConstants.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/JcrConstants.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,343 @@
+/*
+ * 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.util;
+
+/**
+ * This Interface defines some of the item names that are defined in the
+ * jcr spec 2.0 and some that are used in the cq5 platform, using the default
+ * prefixes 'cq', 'jcr', 'nt' and 'mix'.
+ *
+ * Please note that those prefixes can by redefined by an application using the
+ * {@link javax.jcr.Session#setNamespacePrefix(String, String)} method. As a
+ * result, the constants may not refer to the respective items.
+ */
+public interface JcrConstants {
+
+ // basic jcr 1.0 constants
+
+ /**
+ * jcr:autoCreated
+ */
+ public static final String JCR_AUTOCREATED = "jcr:autoCreated";
+ /**
+ * jcr:baseVersion
+ */
+ public static final String JCR_BASEVERSION = "jcr:baseVersion";
+ /**
+ * jcr:child
+ */
+ public static final String JCR_CHILD = "jcr:child";
+ /**
+ * jcr:childNodeDefinition
+ */
+ public static final String JCR_CHILDNODEDEFINITION = "jcr:childNodeDefinition";
+ /**
+ * jcr:content
+ */
+ public static final String JCR_CONTENT = "jcr:content";
+ /**
+ * jcr:created
+ */
+ public static final String JCR_CREATED = "jcr:created";
+ /**
+ * jcr:data
+ */
+ public static final String JCR_DATA = "jcr:data";
+ /**
+ * jcr:defaultPrimaryType
+ */
+ public static final String JCR_DEFAULTPRIMARYTYPE = "jcr:defaultPrimaryType";
+ /**
+ * jcr:defaultValues
+ */
+ public static final String JCR_DEFAULTVALUES = "jcr:defaultValues";
+ /**
+ * jcr:encoding
+ */
+ public static final String JCR_ENCODING = "jcr:encoding";
+ /**
+ * jcr:frozenMixinTypes
+ */
+ public static final String JCR_FROZENMIXINTYPES = "jcr:frozenMixinTypes";
+ /**
+ * jcr:frozenNode
+ */
+ public static final String JCR_FROZENNODE = "jcr:frozenNode";
+ /**
+ * jcr:frozenPrimaryType
+ */
+ public static final String JCR_FROZENPRIMARYTYPE = "jcr:frozenPrimaryType";
+ /**
+ * jcr:frozenUuid
+ */
+ public static final String JCR_FROZENUUID = "jcr:frozenUuid";
+ /**
+ * jcr:hasOrderableChildNodes
+ */
+ public static final String JCR_HASORDERABLECHILDNODES = "jcr:hasOrderableChildNodes";
+ /**
+ * jcr:isCheckedOut
+ */
+ public static final String JCR_ISCHECKEDOUT = "jcr:isCheckedOut";
+ /**
+ * jcr:isMixin
+ */
+ public static final String JCR_ISMIXIN = "jcr:isMixin";
+ /**
+ * jcr:language
+ */
+ public static final String JCR_LANGUAGE = "jcr:language";
+ /**
+ * jcr:lastModified
+ */
+ public static final String JCR_LASTMODIFIED = "jcr:lastModified";
+ /**
+ * jcr:lockIsDeep
+ */
+ public static final String JCR_LOCKISDEEP = "jcr:lockIsDeep";
+ /**
+ * jcr:lockOwner
+ */
+ public static final String JCR_LOCKOWNER = "jcr:lockOwner";
+ /**
+ * jcr:mandatory
+ */
+ public static final String JCR_MANDATORY = "jcr:mandatory";
+ /**
+ * jcr:mergeFailed
+ */
+ public static final String JCR_MERGEFAILED = "jcr:mergeFailed";
+ /**
+ * jcr:mimeType
+ */
+ public static final String JCR_MIMETYPE = "jcr:mimeType";
+ /**
+ * jcr:mixinTypes
+ */
+ public static final String JCR_MIXINTYPES = "jcr:mixinTypes";
+ /**
+ * jcr:multiple
+ */
+ public static final String JCR_MULTIPLE = "jcr:multiple";
+ /**
+ * jcr:name
+ */
+ public static final String JCR_NAME = "jcr:name";
+ /**
+ * jcr:nodeTypeName
+ */
+ public static final String JCR_NODETYPENAME = "jcr:nodeTypeName";
+ /**
+ * jcr:onParentVersion
+ */
+ public static final String JCR_ONPARENTVERSION = "jcr:onParentVersion";
+ /**
+ * jcr:predecessors
+ */
+ public static final String JCR_PREDECESSORS = "jcr:predecessors";
+ /**
+ * jcr:primaryItemName
+ */
+ public static final String JCR_PRIMARYITEMNAME = "jcr:primaryItemName";
+ /**
+ * jcr:primaryType
+ */
+ public static final String JCR_PRIMARYTYPE = "jcr:primaryType";
+ /**
+ * jcr:propertyDefinition
+ */
+ public static final String JCR_PROPERTYDEFINITION = "jcr:propertyDefinition";
+ /**
+ * jcr:protected
+ */
+ public static final String JCR_PROTECTED = "jcr:protected";
+ /**
+ * jcr:requiredPrimaryTypes
+ */
+ public static final String JCR_REQUIREDPRIMARYTYPES = "jcr:requiredPrimaryTypes";
+ /**
+ * jcr:requiredType
+ */
+ public static final String JCR_REQUIREDTYPE = "jcr:requiredType";
+ /**
+ * jcr:rootVersion
+ */
+ public static final String JCR_ROOTVERSION = "jcr:rootVersion";
+ /**
+ * jcr:sameNameSiblings
+ */
+ public static final String JCR_SAMENAMESIBLINGS = "jcr:sameNameSiblings";
+ /**
+ * jcr:statement
+ */
+ public static final String JCR_STATEMENT = "jcr:statement";
+ /**
+ * jcr:successors
+ */
+ public static final String JCR_SUCCESSORS = "jcr:successors";
+ /**
+ * jcr:supertypes
+ */
+ public static final String JCR_SUPERTYPES = "jcr:supertypes";
+ /**
+ * jcr:system
+ */
+ public static final String JCR_SYSTEM = "jcr:system";
+ /**
+ * jcr:uuid
+ */
+ public static final String JCR_UUID = "jcr:uuid";
+ /**
+ * jcr:valueConstraints
+ */
+ public static final String JCR_VALUECONSTRAINTS = "jcr:valueConstraints";
+ /**
+ * jcr:versionHistory
+ */
+ public static final String JCR_VERSIONHISTORY = "jcr:versionHistory";
+ /**
+ * jcr:versionLabels
+ */
+ public static final String JCR_VERSIONLABELS = "jcr:versionLabels";
+ /**
+ * jcr:versionStorage
+ */
+ public static final String JCR_VERSIONSTORAGE = "jcr:versionStorage";
+ /**
+ * jcr:versionableUuid
+ */
+ public static final String JCR_VERSIONABLEUUID = "jcr:versionableUuid";
+
+ /**
+ * Pseudo property jcr:path used with query results
+ */
+ public static final String JCR_PATH = "jcr:path";
+ /**
+ * Pseudo property jcr:score used with query results
+ */
+ public static final String JCR_SCORE = "jcr:score";
+
+ /**
+ * mix:lockable
+ */
+ public static final String MIX_LOCKABLE = "mix:lockable";
+ /**
+ * mix:referenceable
+ */
+ public static final String MIX_REFERENCEABLE = "mix:referenceable";
+ /**
+ * mix:versionable
+ */
+ public static final String MIX_VERSIONABLE = "mix:versionable";
+ /**
+ * nt:base
+ */
+ public static final String NT_BASE = "nt:base";
+ /**
+ * nt:childNodeDefinition
+ */
+ public static final String NT_CHILDNODEDEFINITION = "nt:childNodeDefinition";
+ /**
+ * nt:file
+ */
+ public static final String NT_FILE = "nt:file";
+ /**
+ * nt:folder
+ */
+ public static final String NT_FOLDER = "nt:folder";
+ /**
+ * nt:frozenNode
+ */
+ public static final String NT_FROZENNODE = "nt:frozenNode";
+ /**
+ * nt:hierarchyNode
+ */
+ public static final String NT_HIERARCHYNODE = "nt:hierarchyNode";
+ /**
+ * nt:linkedFile
+ */
+ public static final String NT_LINKEDFILE = "nt:linkedFile";
+ /**
+ * nt:nodeType
+ */
+ public static final String NT_NODETYPE = "nt:nodeType";
+ /**
+ * nt:propertyDefinition
+ */
+ public static final String NT_PROPERTYDEFINITION = "nt:propertyDefinition";
+ /**
+ * nt:query
+ */
+ public static final String NT_QUERY = "nt:query";
+ /**
+ * nt:resource
+ */
+ public static final String NT_RESOURCE = "nt:resource";
+ /**
+ * nt:unstructured
+ */
+ public static final String NT_UNSTRUCTURED = "nt:unstructured";
+ /**
+ * nt:version
+ */
+ public static final String NT_VERSION = "nt:version";
+ /**
+ * nt:versionHistory
+ */
+ public static final String NT_VERSIONHISTORY = "nt:versionHistory";
+ /**
+ * nt:versionLabels
+ */
+ public static final String NT_VERSIONLABELS = "nt:versionLabels";
+ /**
+ * nt:versionedChild
+ */
+ public static final String NT_VERSIONEDCHILD = "nt:versionedChild";
+
+ // future JSR283 item and node type names
+
+ /**
+ * jcr:title
+ */
+ public static final String JCR_TITLE = "jcr:title";
+ /**
+ * jcr:description
+ */
+ public static final String JCR_DESCRIPTION = "jcr:description";
+ /**
+ * jcr:createdBy
+ */
+ public static final String JCR_CREATED_BY = "jcr:createdBy";
+ /**
+ * jcr:lastModifiedBy
+ */
+ public static final String JCR_LAST_MODIFIED_BY = "jcr:lastModifiedBy";
+ /**
+ * mix:title
+ */
+ public static final String MIX_TITLE = "mix:title";
+ /**
+ * mix:created
+ */
+ public static final String MIX_CREATED = "mix:created";
+ /**
+ * mix:lastModified
+ */
+ public static final String MIX_LAST_MODIFIED = "mix:lastModified";
+
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/LineInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/LineInputStream.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/LineInputStream.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/LineInputStream.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,167 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Provides an input stream wrapper that detects line feed sequences and
+ * replaces them by new ones.
+ *
+ */
+public class LineInputStream extends InputStream {
+
+ public static final byte[] LS_UNIX = new byte[]{0x0a};
+
+ public static final byte[] LS_WINDOWS = new byte[]{0x0d, 0x0a};
+
+ public static final byte[] LS_NATIVE = System.getProperty("line.separator").getBytes();
+
+ private byte[] buffer = new byte[8192];
+
+ private byte[] lineFeed = LS_NATIVE;
+
+ private byte[] lineSpool;
+
+ private int pos = 0;
+
+ private int end = 0;
+
+ private static final char STATE_INIT = ' ';
+ private static final char STATE_CR = 'c';
+ private static final char STATE_LF = 'l';
+ private static final char STATE_CRLF = 'f';
+
+ private char state = STATE_INIT;
+
+ boolean isEof = false;
+
+ private byte[] spool;
+
+ private int spoolPos = 0;
+
+ private final InputStream in;
+
+ public LineInputStream(InputStream in, byte[] ls) {
+ this.in = in;
+ if (ls != null) {
+ lineFeed = ls;
+ }
+ lineSpool = new byte[lineFeed.length + 1];
+ System.arraycopy(lineFeed, 0, lineSpool, 0, lineFeed.length);
+ }
+
+ private int fillBuffer() throws IOException {
+ int ret = in.read(buffer, end, buffer.length - end);
+ if (ret >= 0) {
+ end += ret;
+ } else {
+ isEof = true;
+ }
+ return ret;
+ }
+
+ public int read() throws IOException {
+ final byte[] one = new byte[1];
+ if (read(one) == -1) {
+ return -1;
+ }
+ return one[0];
+ }
+
+ public int read(byte b[], int off, int len) throws IOException {
+ if (isEof) {
+ if (spool == null) {
+ if (state != STATE_INIT) {
+ spool = lineFeed;
+ state = STATE_INIT;
+ } else {
+ return -1;
+ }
+ }
+ }
+ int total = 0;
+ while (total < len) {
+ if (spool != null) {
+ b[off+(total++)] = spool[spoolPos++];
+ if (spoolPos == spool.length) {
+ spool = null;
+ spoolPos = 0;
+ }
+ } else {
+ if (pos == end) {
+ int ret = fillBuffer();
+ if (ret == 0 && pos == end) {
+ // in this case we didn't get more, so flush
+ pos = end = 0;
+ continue;
+ } else if (ret == -1) {
+ break;
+ }
+ }
+ byte c = buffer[pos++];
+ if (c == 0x0a) {
+ switch (state) {
+ case STATE_INIT:
+ state = STATE_LF;
+ break;
+ case STATE_CR:
+ state = STATE_CRLF;
+ break;
+ case STATE_LF:
+ spool = lineFeed;
+ break;
+ case STATE_CRLF:
+ spool = lineFeed;
+ state = STATE_LF;
+ }
+ } else if (c == 0x0d) {
+ switch (state) {
+ case STATE_INIT:
+ state = STATE_CR;
+ break;
+ case STATE_LF:
+ state = STATE_CRLF;
+ break;
+ case STATE_CR:
+ spool = lineFeed;
+ break;
+ case STATE_CRLF:
+ spool = lineFeed;
+ state = STATE_CR;
+ }
+ } else {
+ if (state != STATE_INIT) {
+ spool = lineSpool;
+ lineSpool[lineSpool.length - 1] = c;
+ state = STATE_INIT;
+ } else {
+ b[off + (total++)] = c;
+ }
+ }
+ }
+ }
+ return total;
+ }
+
+ public void close() throws IOException {
+ in.close();
+ }
+
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/LineOutputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/LineOutputStream.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/LineOutputStream.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/LineOutputStream.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,125 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Provides an output stream wrapper that detects line feed sequences and
+ * replaces them by new ones.
+ *
+ */
+public class LineOutputStream extends OutputStream {
+
+ public static final byte[] LS_BINARY = null;
+
+ public static final byte[] LS_UNIX = new byte[]{0x0a};
+
+ public static final byte[] LS_WINDOWS = new byte[]{0x0d, 0x0a};
+
+ public static final byte[] LS_NATIVE = System.getProperty("line.separator").getBytes();
+
+ private byte[] buffer = new byte[8192];
+
+ private byte[] lineFeed = LS_NATIVE;
+
+ private int pos = 0;
+
+ private static final char STATE_INIT = ' ';
+ private static final char STATE_CR = 'c';
+ private static final char STATE_LF = 'l';
+ private static final char STATE_CRLF = 'f';
+
+ private char state = STATE_INIT;
+
+ private final OutputStream out;
+
+ public LineOutputStream(OutputStream out, byte[] ls) {
+ this.out = out;
+ if (ls != null) {
+ this.lineFeed = ls;
+ }
+ }
+
+ public void write(int b) throws IOException {
+ if (b == 0x0a) {
+ switch (state) {
+ case STATE_INIT:
+ state = STATE_LF;
+ break;
+ case STATE_CR:
+ state = STATE_CRLF;
+ break;
+ case STATE_LF:
+ flush(true);
+ state = STATE_LF;
+ break;
+ case STATE_CRLF:
+ flush(true);
+ state = STATE_LF;
+ }
+ } else if (b == 0x0d) {
+ switch (state) {
+ case STATE_INIT:
+ state = STATE_CR;
+ break;
+ case STATE_LF:
+ state = STATE_CRLF;
+ break;
+ case STATE_CR:
+ flush(true);
+ state = STATE_CR;
+ break;
+ case STATE_CRLF:
+ flush(true);
+ state = STATE_CR;
+ }
+ } else {
+ if (state != STATE_INIT) {
+ flush(true);
+ state = STATE_INIT;
+ }
+ if (pos == buffer.length) {
+ flush();
+ }
+ buffer[pos++] = (byte) (b & 0xff);
+ }
+ }
+
+ public void flush(boolean addLF) throws IOException {
+ flush();
+ if (addLF) {
+ out.write(lineFeed);
+ }
+ out.flush();
+ }
+
+ public void flush() throws IOException {
+ out.write(buffer, 0, pos);
+ pos = 0;
+ out.flush();
+ }
+
+ public void close() throws IOException {
+ // check for pending lfs
+ flush(state != STATE_INIT);
+ out.close();
+ }
+
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/MD5.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/MD5.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/MD5.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/MD5.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,139 @@
+/*
+ * 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.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * <code>MD5</code>...
+ */
+public class MD5 {
+
+ private final long msb;
+
+ private final long lsb;
+
+ public MD5(long msb, long lsb) {
+ this.msb = msb;
+ this.lsb = lsb;
+ }
+
+ public MD5(String str) {
+ if (str.length() != 32) {
+ throw new IllegalArgumentException("invalid string length " + str.length());
+ }
+ msb = (Long.parseLong(str.substring(0, 8), 16) << 32)
+ + (Long.parseLong(str.substring(8, 16), 16));
+ lsb = (Long.parseLong(str.substring(16, 24), 16) << 32)
+ + (Long.parseLong(str.substring(24, 32), 16));
+ }
+
+ public MD5(byte[] bytes) {
+ if (bytes.length != 16) {
+ throw new IllegalArgumentException("invalid bytes length " + bytes.length);
+ }
+ msb = getLong(bytes, 0);
+ lsb = getLong(bytes, 8);
+ }
+
+ public long[] getLongs() {
+ return new long[]{msb, lsb};
+ }
+
+ public long getMsb() {
+ return msb;
+ }
+
+ public long getLsb() {
+ return lsb;
+ }
+
+ public byte[] getBytes() {
+ byte[] buf = new byte[16];
+ setLong(buf, 0, msb);
+ setLong(buf, 8, lsb);
+ return buf;
+ }
+
+ public static MD5 digest(InputStream in) throws IOException {
+ try {
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance("md5");
+ } catch (NoSuchAlgorithmException e) {
+ throw new IllegalArgumentException(e.toString());
+ }
+ byte[] buffer = new byte[8192];
+ int read;
+ while ((read = in.read(buffer)) > 0) {
+ md.update(buffer, 0, read);
+ }
+ return new MD5(md.digest());
+ } finally {
+ in.close();
+ }
+ }
+
+ public static MD5 digest(File file) throws IOException {
+ return digest(new FileInputStream(file));
+ }
+
+ public String toString() {
+ return String.format("%016x%016x", msb, lsb);
+ }
+
+ public int hashCode() {
+ return (int)((msb >> 32) ^ msb ^ (lsb >> 32) ^ lsb);
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MD5 md5 = (MD5) o;
+ return lsb == md5.lsb && msb == md5.msb;
+ }
+
+ private static long getLong(byte[] b, int offs) {
+ return ((long) (b[offs] & 0xFF) << 56) +
+ ((long) (b[1 + offs] & 0xFF) << 48) +
+ ((long) (b[2 + offs] & 0xFF) << 40) +
+ ((long) (b[3 + offs] & 0xFF) << 32) +
+ ((long) (b[4 + offs] & 0xFF) << 24) +
+ ((long) (b[5 + offs] & 0xFF) << 16) +
+ ((long) (b[6 + offs] & 0xFF) << 8) +
+ ((long) (b[7 + offs] & 0xFF));
+ }
+
+ private static void setLong(byte[] b, int offs, long v) {
+ b[offs] = (byte) ((v >>> 56) & 0xFF);
+ b[offs+1] = (byte) ((v >>> 48) & 0xFF);
+ b[offs+2] = (byte) ((v >>> 40) & 0xFF);
+ b[offs+3] = (byte) ((v >>> 32) & 0xFF);
+ b[offs+4] = (byte) ((v >>> 24) & 0xFF);
+ b[offs+5] = (byte) ((v >>> 16) & 0xFF);
+ b[offs+6] = (byte) ((v >>> 8) & 0xFF);
+ b[offs+7] = (byte) ((v >>> 0) & 0xFF);
+ }
+
+
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/MimeTypes.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/MimeTypes.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/MimeTypes.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/MimeTypes.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,221 @@
+/*
+ * 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.util;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+
+/**
+ * <code>MimeTypes</code> contains a mapping from extensions to mime types.
+ *
+ */
+public class MimeTypes {
+
+ /**
+ * constant for {@value}
+ */
+ public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";
+
+ /**
+ * mapping from content-type to {@link MimeType}s.
+ */
+ private static final HashMap<String, MimeType> byMimeType = new HashMap<String, MimeType>();
+
+ /**
+ * mapping from extension to {@link MimeType}s.
+ */
+ private static final HashMap<String, MimeType> byExtension = new HashMap<String, MimeType>();
+
+ static {
+ // add some default mappings
+ addMapping(false, "text/plain", "txt", "jsp", "jspx", "jspf", "ecma", "esp", "xsl", "xslt", "dtd", "properties", "tld" ,"php", "rb", "bnd");
+ addMapping(false, "text/cnd" , "cnd");
+ addMapping(false, "text/x-java-source" , "java");
+ addMapping(true, "application/java-vm" , "class");
+ addMapping(false, "text/html" , "html", "htm");
+ addMapping(false, "text/xml" , "xml");
+ addMapping(false, "text/css" , "css", "less");
+ addMapping(false, "text/calendar", "ics");
+ addMapping(false, "image/svg+xml", "svg");
+ addMapping(false, "application/xliff+xml" , "xliff");
+ addMapping(true, "image/gif" , "gif");
+ addMapping(true, "image/png" , "png");
+ addMapping(true, "image/jpeg", "jpg", "jpeg");
+ addMapping(true, "image/jpg" , "jpg", "jpeg"); // this is for compatibility reasons
+ addMapping(false, "application/json", "json");
+ addMapping(true, "application/java-archive", "jar");
+ addMapping(false, "application/javascript", "js");
+ addMapping(false, "application/ecmascript", "ecma");
+ addMapping(false, "application/x-javascript", "js"); // discouraged per RFC-4329
+ addMapping(true, "application/pdf", "pdf");
+ addMapping(true, "application/x-shockwave-flash", "swf");
+ addMapping(true, "application/zip", "zip");
+ addMapping(true, "image/vnd.microsoft.icon", "ico");
+ addMapping(true, "application/x-font-woff", "woff");
+ addMapping(true, "application/vnd.ms-fontobject", "eot");
+ }
+
+ /**
+ * internally add a mapping to the static defined ones
+ * @param binary binary flag
+ * @param mimeType the content type
+ * @param ext extensions
+ */
+ private static void addMapping(boolean binary, String mimeType, String ... ext) {
+ if (byMimeType.containsKey(mimeType)) {
+ throw new IllegalArgumentException("MimeType already registered:" + mimeType);
+ }
+ MimeType mt = new MimeType(mimeType, binary, ext);
+ byMimeType.put(mimeType, mt);
+ for (String e: ext) {
+ if (!byExtension.containsKey(e)) {
+ // only register default mime type
+ byExtension.put(e, mt);
+ }
+ }
+ }
+
+ /**
+ * Retrieve the mimetype for the given extension or name
+ * @param name the name
+ * @return the mimetype or <code>null</code>
+ */
+ public static String getMimeType(String name) {
+ return getMimeType(name, null);
+ }
+
+ /**
+ * Retrieve the mimetype for the given extension or name
+ * @param name the name
+ * @param defaultType type to return if no mapping is found.
+ * @return the mimetype or <code>null</code>
+ */
+ public static String getMimeType(String name, String defaultType) {
+ name = name.substring(name.lastIndexOf('.') + 1);
+ MimeType mt = byExtension.get(name);
+ if (mt == null) {
+ return defaultType;
+ } else {
+ return mt.mimeType;
+ }
+ }
+
+ /**
+ * Retrieve the default extension for the given mime type
+ * @param mimeType the mime type
+ * @return the extension or null
+ */
+ public static String getExtension(String mimeType) {
+ MimeType mt = byMimeType.get(mimeType);
+ if (mt == null) {
+ return null;
+ } else {
+ return mt.defaultExt;
+ }
+ }
+
+ /**
+ * checks if the given mimetype denotes binary content
+ * @param mimeType the mime type
+ * @return <code>true</code> if binary or if <code>mimeType</code> is <code>null</code>
+ */
+ public static boolean isBinary(String mimeType) {
+ if (mimeType == null) {
+ return true;
+ }
+ if (mimeType.startsWith("text/")) {
+ return false;
+ }
+ MimeType mt = byMimeType.get(mimeType);
+ return mt == null || mt.isBinary();
+ }
+
+ /**
+ * Checks if the given mime type is mapped to the extension
+ * @param mimeType the mime type
+ * @param ext the extension
+ * @return <code>true</code> if the given mime type contains that extension
+ */
+ public static boolean hasExtension(String mimeType, String ext) {
+ MimeType mt = byMimeType.get(mimeType);
+ return mt != null && mt.extensions.contains(ext);
+ }
+
+ public static boolean matches(String name, String mimeType, String defaultType) {
+ name = name.substring(name.lastIndexOf('.') + 1);
+ MimeType mt = byExtension.get(name);
+ if (mt != null && mt.mimeType.equals(mimeType)) {
+ return true;
+ }
+ // try reverse mapping
+ mt = byMimeType.get(mimeType);
+ if (mt != null && mt.extensions.contains(name)) {
+ return true;
+ }
+ return mimeType.equals(defaultType);
+ }
+
+ /**
+ * holds the mime type to extension mappings
+ */
+ private static class MimeType {
+
+ /**
+ * the mime type
+ */
+ private final String mimeType;
+
+ /**
+ * the default extension
+ */
+ private final String defaultExt;
+
+ /**
+ * set of all extensions
+ */
+ private final HashSet<String> extensions = new HashSet<String>();
+
+ /**
+ * binary flag
+ */
+ private final boolean binary;
+
+ /**
+ * creates a new mapping
+ * @param mimeType the mime type
+ * @param binary binary flag
+ * @param ext the extensions
+ */
+ public MimeType(String mimeType, boolean binary, String ... ext) {
+ this.mimeType = mimeType;
+ this.binary = binary;
+ this.defaultExt = ext[0];
+ extensions.addAll(Arrays.asList(ext));
+ }
+
+ /**
+ * Returns <code>true</code> if this is a binary mime type
+ * @return <code>true</code> if binary.
+ *
+ */
+ public boolean isBinary() {
+ return binary;
+ }
+ }
+}
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/NodeNameComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/NodeNameComparator.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/NodeNameComparator.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/NodeNameComparator.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,53 @@
+/*
+ * 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.util;
+
+import java.util.Comparator;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>ItemNameComparator</code>...
+ */
+public class NodeNameComparator implements Comparator<Node> {
+
+ public static final NodeNameComparator INSTANCE = new NodeNameComparator();
+
+ public int compare(Node o1, Node o2) {
+ try {
+ // sort namespaced first
+ String n1 = o1.getName().toLowerCase();
+ String n2 = o2.getName().toLowerCase();
+ int i1 = n1.indexOf(':');
+ int i2 = n2.indexOf(':');
+ if (i1 >=0 && i2 < 0) {
+ return -1;
+ } else if (i1 < 0 && i2 >=0) {
+ return 1;
+ } else if (n1.equals(n2)) {
+ // compare indexes for SNS
+ return o1.getIndex() - o2.getIndex();
+ } else {
+ return n1.compareTo(n2);
+ }
+ } catch (RepositoryException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PathComparator.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PathComparator.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PathComparator.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PathComparator.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,88 @@
+/*
+ * 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.util;
+
+import java.util.Comparator;
+
+/**
+ * <code>PathComparator</code>...
+ *
+ */
+public class PathComparator implements Comparator<String> {
+
+ private final char separator;
+
+ private boolean reverse;
+
+ public PathComparator() {
+ separator = '/';
+ }
+
+ public PathComparator(boolean reverse) {
+ separator = '/';
+ this.reverse = reverse;
+ }
+
+ public PathComparator(char separator) {
+ this.separator = separator;
+ }
+
+ public PathComparator(char separator, boolean reverse) {
+ this.separator = separator;
+ this.reverse = reverse;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * Compared to the {@link String#compareTo(String)} it handles the '/'
+ * differently giving it the highest priority so that:
+ *
+ * "/a" < "/b"
+ * "/a1foo" < "/a/foo"
+ */
+ public int compare(String o1, String o2) {
+ if (o1.equals(o2)) {
+ return 0;
+ }
+ int last0 = 0;
+ int last1 = 0;
+ int i0 = o1.indexOf(separator, 1);
+ int i1 = o2.indexOf(separator, 1);
+ while (i0 > 0 && i1 > 0) {
+ int c = o1.substring(last0, i0).compareTo(o2.substring(last1, i1));
+ if (c != 0) {
+ return reverse ? -c : c;
+ }
+ last0 = i0;
+ last1 = i1;
+ i0 = o1.indexOf(separator, i0 + 1);
+ i1 = o2.indexOf(separator, i1 + 1);
+ }
+ int ret;
+ if (i0 > 0) {
+ ret = 1;
+ } else if (i1 > 0) {
+ ret = -1;
+ } else {
+ // compare last segment
+ ret = o1.substring(last0).compareTo(o2.substring(last1));
+ }
+ return reverse ? -ret : ret;
+ }
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PathUtil.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PathUtil.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PathUtil.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PathUtil.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,184 @@
+/*
+ * 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.util;
+
+import java.io.File;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>PathUtil</code>...
+ *
+ */
+public class PathUtil {
+
+ /**
+ * make a canonical path. removes all /./ and /../ and multiple slashes.
+ * @param parent the parent path (can be <code>null</code>)
+ * @param path the path to resolve
+ * @return the canonicalized path
+ */
+ public static String[] makePath(String[] parent, String path) {
+ if (path == null || path.equals("") || path.equals(".")) {
+ return parent;
+ }
+ // compose parent and path
+ boolean isAbsolute = false;
+ String[] composed = Text.explode(path, '/');
+ if (path.charAt(0) == '/') {
+ isAbsolute = true;
+ } else {
+ if (parent != null && parent.length > 0) {
+ int off = 0;
+ if (parent[0].equals("/")) {
+ isAbsolute = true;
+ off = 1;
+ }
+ String[] c = new String[parent.length - off + composed.length];
+ System.arraycopy(parent, off, c, 0, parent.length - off);
+ System.arraycopy(composed, 0, c, parent.length - off, composed.length);
+ composed = c;
+ }
+ }
+ // canonicalize
+ int dst = 0;
+ boolean startsWithParent = false;
+ for (int i=0; i<composed.length; i++) {
+ String element = composed[i];
+ if (element.equals(".")) {
+ // skip
+ } else if (element.equals("..")) {
+ if (dst == 0) {
+ startsWithParent = true;
+ }
+ if (startsWithParent) {
+ composed[dst++] = element;
+ } else {
+ dst--;
+ }
+ } else {
+ composed[dst++] = element;
+ }
+ }
+ // truncate
+ if (isAbsolute) {
+ String[] ret = new String[dst + 1];
+ System.arraycopy(composed, 0, ret, 1, dst);
+ ret[0] = "/";
+ return ret;
+ } else if (dst == composed.length) {
+ return composed;
+ } else {
+ String[] ret = new String[dst];
+ System.arraycopy(composed, 0, ret, 0, dst);
+ return ret;
+ }
+ }
+
+ public static String makePath(String parent, String relPath) {
+ String[] ret = makePath(Text.explode(parent, '/'), relPath);
+ return "/" + Text.implode(ret, "/");
+ }
+
+ public static File getRelativeFile(File parent, File file) {
+ return new File(getRelativeFilePath(parent.getPath(), file.getPath()));
+ }
+
+ public static String getRelativePath(String parent, String path) {
+ return getRelativeFilePath(parent, path, "/");
+ }
+
+ public static String getRelativeFilePath(String cwd, String path) {
+ return getRelativeFilePath(cwd, path, Constants.FS_NATIVE);
+ }
+
+ public static String getRelativeFilePath(String cwd, String path, String separator) {
+ if (cwd.equals(path)) {
+ return ".";
+ }
+ if (!path.startsWith(separator)) {
+ // check for windows abs paths
+ if (path.length() < 2 || path.charAt(1) != ':' || path.charAt(2) != '\\') {
+ return path;
+ }
+ }
+ String[] p1 = Text.explode(cwd, separator.charAt(0));
+ String[] p2 = Text.explode(path, separator.charAt(0));
+ // search common ancestor
+ int i=0;
+ while (i<p1.length && i<p2.length && p1[i].equals(p2[i])) {
+ i++;
+ }
+ StringBuffer buf = new StringBuffer();
+ String delim = "";
+ // go p1.length - i levels up to the common ancestor
+ for (int j = i; j<p1.length; j++) {
+ buf.append(delim).append("..");
+ delim = separator;
+ }
+ // append rest of path
+ while (i<p2.length) {
+ buf.append(delim).append(p2[i++]);
+ delim = separator;
+ }
+ return buf.toString();
+ }
+
+ public static String append(String parent, String relPath) {
+ if (relPath == null || relPath.length() == 0) {
+ return parent == null ? "" : parent;
+ }
+ StringBuffer ret = new StringBuffer();
+ if (parent != null) {
+ ret.append(parent);
+ }
+ if (ret.length() > 0 && ret.charAt(ret.length()-1) != '/') {
+ ret.append('/');
+ }
+ ret.append(relPath);
+ return ret.toString();
+ }
+
+ public static int getDepth(String path) {
+ // assume valid absolute path
+ int len = path.length();
+ if (len <=1) {
+ return 0;
+ }
+ int depth = 1;
+ for (int i=1; i<len; i++) {
+ if (path.charAt(i) == '/') {
+ depth++;
+ }
+ }
+ return depth;
+ }
+
+ public static String getPath(Node parent, String relPath) throws RepositoryException {
+ String path = parent.getPath();
+ if (relPath.length() > 0) {
+ if (path.endsWith("/")) {
+ path += relPath;
+ } else {
+ path += "/" + relPath;
+ }
+ }
+ return path;
+ }
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PlatformNameFormat.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PlatformNameFormat.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PlatformNameFormat.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/PlatformNameFormat.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,208 @@
+/*
+ * 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.util;
+
+/**
+ * Implements a repository to platform name formatter. Illegal characters a
+ * generally escaped using the url escaping format, i.e. replacing the char
+ * by a '%' hex(char) sequence. special treatment is used for the ':' char
+ * since it's used quite often as namespace prefix separator. the
+ * PREFIX ':' NAME sequence is replaced by '_' PREFIX '_' NAME. item names
+ * that would generate the same pattern are escaped with an extra leading '_'.
+ *
+ * examples:
+ *
+ * +-------------------+----------------------+----+----+
+ * | repository name | platform name | pp | sp |
+ * +-------------------+----------------------+----+----+
+ * | test.jpg | test.jpg | -1 | -1 |
+ * | cq:content | _cq_content | 2 | -1 |
+ * | cq:test_image.jpg | _cq_test_image.jpg | 2 | 7 |
+ * | test_image.jpg | test_image.jpg | -1 | 4 |
+ * | _testimage.jpg | _testimage.jpg | -1 | 0 |
+ * | _test_image.jpg | __test_image.jpg | -1 | 0 |
+ * +-------------------+----------------------+----+----+
+ * | cq:test:image.jpg | _cq_test%3aimage.jpg | 2 | -1 |
+ * | _cq_:test.jpg | __cq_%3atest.jpg | 4 | 0 |
+ * | _cq:test.jpg | __cq%3atest.jpg | 3 | 0 |
+ * | cq_:test.jpg | cq_%3atest.jpg | 3 | 2 |
+ * +-------------------+----------------------+----+----+
+ *
+ * note for the 2nd set of examples the cases are very rare and justify the
+ * ugly '%' escaping.
+ *
+ */
+public class PlatformNameFormat {
+
+ /**
+ * Returns the platform name for a given repository name. Unsupported
+ * characters are URL escaped (i.e. %xx).
+ *
+ * Note: Forward slashes '/' are not escaped since they never occur in a
+ * jcr name. so this method can also be used to encode paths.
+ *
+ * @param repositoryName the repository name
+ * @return the (escaped) platform name.
+ */
+ public static String getPlatformName(String repositoryName) {
+ StringBuffer buf = new StringBuffer("_");
+ boolean escapeColon = false;
+ boolean useUnderscore = false;
+ int numUnderscore = 0;
+ for (int i=0; i<repositoryName.length(); i++) {
+ char c = repositoryName.charAt(i);
+ switch (c) {
+ case':':
+ if (!escapeColon && i>0) {
+ // pure prefix
+ escapeColon = true;
+ useUnderscore = true;
+ numUnderscore = 2;
+ buf.append('_');
+ } else {
+ buf.append("%3a");
+ }
+ break;
+ case '_':
+ if (i==0) {
+ useUnderscore = true;
+ }
+ numUnderscore++;
+ escapeColon=true;
+ buf.append(c);
+ break;
+ case'\\':
+ case'<':
+ case'>':
+ case'|':
+ case'\"':
+ case '/':
+ case'?':
+ case'%':
+ buf.append('%');
+ buf.append(Character.forDigit(c / 16, 16));
+ buf.append(Character.forDigit(c % 16, 16));
+ break;
+ default:
+ buf.append(c);
+ }
+ }
+ if (useUnderscore && numUnderscore > 1) {
+ return buf.toString();
+ } else {
+ return buf.substring(1);
+ }
+ }
+
+ /**
+ * Returns the platform path for the given repository one.
+ * @param repoPath the repository path
+ * @return the platform path
+ */
+ public static String getPlatformPath(String repoPath) {
+ String[] elems = Text.explode(repoPath, '/', true);
+ for (int i=0; i<elems.length; i++) {
+ if (elems[i].length() > 0) {
+ elems[i] = getPlatformName(elems[i]);
+ }
+ }
+ return Text.implode(elems, "/");
+ }
+
+ /**
+ * Returns the repository name for a given platform name.
+ *
+ * @param platformName the platform name
+ * @return the (unescaped) repository name.
+ */
+ public static String getRepositoryName(String platformName) {
+ StringBuffer buffer = new StringBuffer("_");
+ boolean firstUnderscore = false;
+ for (int i=0; i<platformName.length(); i++) {
+ char c = platformName.charAt(i);
+ if (c == '%') {
+ if (platformName.length() > i+2) {
+ int a = Character.digit(platformName.charAt(++i), 16);
+ int b = Character.digit(platformName.charAt(++i), 16);
+ c = (char) (a * 16 + b);
+ }
+ } else if (c == '_') {
+ if (i==0) {
+ firstUnderscore = true;
+ if (platformName.length()>1) {
+ c = platformName.charAt(++i);
+ if (c == '_') {
+ buffer.append('_');
+ firstUnderscore = false;
+ } else {
+ buffer.append(c);
+ }
+ }
+ continue;
+ } else if (firstUnderscore) {
+ c = ':';
+ firstUnderscore = false;
+ }
+ }
+ buffer.append(c);
+ }
+ if (firstUnderscore) {
+ // pending underscore
+ return buffer.toString();
+ } else {
+ return buffer.substring(1);
+ }
+ }
+
+ /**
+ * Returns the repository path for the given platform one.
+ * @param path the platform path
+ * @return the repository path
+ */
+ public static String getRepositoryPath(String path) {
+ String[] elems = Text.explode(path, '/', true);
+ for (int i=0; i<elems.length; i++) {
+ if (elems[i].length() > 0) {
+ elems[i] = getRepositoryName(elems[i]);
+ }
+ }
+ return Text.implode(elems, "/");
+ }
+
+ /**
+ * Returns the repository path for the given platform one.
+ * @param path the platform path
+ * @param respectDotDir if <code>true</code>, all ".dir" are removed.
+ * @return the repository path
+ */
+ public static String getRepositoryPath(String path, boolean respectDotDir) {
+ String[] elems = Text.explode(path, '/', true);
+ for (int i=0; i<elems.length; i++) {
+ if (elems[i].length() > 0) {
+ if (respectDotDir && elems[i].endsWith(".dir")) {
+ elems[i] = getRepositoryName(elems[i].substring(0, elems[i].length() - 4));
+ } else {
+ elems[i] = getRepositoryName(elems[i]);
+ }
+ }
+ }
+ return Text.implode(elems, "/");
+ }
+
+
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/RejectingEntityDefaultHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/RejectingEntityDefaultHandler.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/RejectingEntityDefaultHandler.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/RejectingEntityDefaultHandler.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,45 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Default handler with special entity resolver that handles all entity resolution requests by returning an empty input
+ * source. This is to prevent "Arbitrary DTD inclusion in XML parsing".
+ */
+public class RejectingEntityDefaultHandler extends DefaultHandler {
+
+ /**
+ * default logger
+ */
+ private static final Logger log = LoggerFactory.getLogger(RejectingEntityDefaultHandler.class);
+
+ @Override
+ public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException {
+ log.warn("Rejecting external entity loading with publicId={} systemId={}", publicId, systemId);
+ return new InputSource(new StringReader(""));
+ }
+}
\ No newline at end of file
Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/RejectingEntityResolver.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/RejectingEntityResolver.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/RejectingEntityResolver.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/util/RejectingEntityResolver.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,46 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Entity resolver that handles all entity resolution requests by returning an empty input source.
+ * This is to prevent "Arbitrary DTD inclusion in XML parsing".
+ */
+public class RejectingEntityResolver implements EntityResolver {
+
+ /**
+ * default logger
+ */
+ private static final Logger log = LoggerFactory.getLogger(RejectingEntityResolver.class);
+
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws SAXException, IOException {
+ log.warn("Rejecting external entity loading with publicId={} systemId={}", publicId, systemId);
+ return new InputSource(new StringReader(""));
+ }
+
+}
\ No newline at end of file