Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/Bytes.java ------------------------------------------------------------------------------ svn = Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/Bytes.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/Constants.java URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/Constants.java?rev=180346&view=auto ============================================================================== --- incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/Constants.java (added) +++ incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/Constants.java Mon Jun 6 10:36:09 2005 @@ -0,0 +1,191 @@ +/* + * Copyright 2004-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed 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.util.uuid; + +/** + *
Constant values commonly needed in the uuid classes.
+ * + *Copied from the Jakarta Commons-Id project
+ * + * todo remove and use official commons-id release as soon as it is available + */ +public interface Constants { + + //** Magic number constants + /** + * Bits in a UUID. + */ + int UUID_BIT_LENGTH = 128; + + /** + * Number of bytes in a UUID. + */ + int UUID_BYTE_LENGTH = 16; + + + //** Formatting and validation constants + /** + * Chars in a UUID String. + */ + int UUID_UNFORMATTED_LENGTH = 32; + + /** + * Chars in a UUID String. + */ + int UUID_FORMATTED_LENGTH = 36; + + /** + * Token length of '-' separated tokens. + */ + int TOKENS_IN_UUID = 5; + + /** + * Array to check tokenized UUID's segment lengths + */ + int[] TOKEN_LENGTHS = {8, 4, 4, 4, 12}; + + /** + * Insertion point 1 for dashes in the string format + */ + int FORMAT_POSITION1 = 8; + + /** + * Insertion point 2 for dashes in the string format + */ + int FORMAT_POSITION2 = 13; + + /** + * Insertion point 3 for dashes in the string format + */ + int FORMAT_POSITION3 = 18; + + /** + * Insertion point 4 for dashes in the string format + */ + int FORMAT_POSITION4 = 23; + + /** + * The string prefix for a urn UUID identifier. + */ + String URN_PREFIX = "urn:uuid:"; + + + //** UUID Variant QueryConstants + /** + * UUID variant bits described in the IETF Draft MSB order, + * this is the "Reserved, NCS backward compatibility field" 0 x x with unknown bits as 0 + */ + int VARIANT_NCS_COMPAT = 0; + + /** + * UUID variant bits described in the IETF Draft MSB order, + * this is the IETF Draft memo variant field 1 0 x with unknown bits as 0 + */ + int VARIANT_IETF_DRAFT = 2; + + /** + * UUID variant bits described in the IETF Draft MSB order, + * this is the IETF Draft "Microsoft Corporation" field variant 1 1 0 x with unknown bits as 0 + */ + int VARIANT_MS = (byte) 6; + + /** + * UUID variant bits described in the IETF Draft MSB order, + * this is the "Future Reserved variant 1 1 1 x with unknown bits as 0 + */ + int VARIANT_FUTURE = 7; + + + //** UUID Version QueryConstants + /** + * Version one constant for UUID version one of four + */ + int VERSION_ONE = 1; + + /** + * Version two constant for UUID version two of four + */ + int VERSION_TWO = 2; + + /** + * Version three constant for UUID version three of four + */ + int VERSION_THREE = 3; + + /** + * Version four constant for UUID version four of four + */ + int VERSION_FOUR = 4; + + //** Exception message constants + /** + * Message indicating this is not a version one UUID + */ + String WRONG_VAR_VER_MSG = "Not a ietf variant 2 or version 1 (time-based UUID)"; + + // ** Array positions and lengths of UUID fields ** // + /** + * Byte length of time low field + */ + int TIME_LOW_BYTE_LEN = 4; + /** + * Byte length of time low field + */ + int TIME_MID_BYTE_LEN = 2; + /** + * Byte length of time low field + */ + int TIME_HI_BYTE_LEN = 2; + /** + * Timestamp byte[] position of time low field + */ + int TIME_LOW_TS_POS = 4; + /** + * Timestamp byte[] position mid field + */ + int TIME_MID_TS_POS = 2; + /** + * Timestamp byte[] position hi field + */ + int TIME_HI_TS_POS = 0; + /** + * uuid array position start of time low field + */ + int TIME_LOW_START_POS = 0; + /** + * uuid array position start of mid field + */ + int TIME_MID_START_POS = 4; + /** + * uuid array position start of hi field + */ + int TIME_HI_START_POS = 6; + /** + * Byte position of the clock sequence and reserved field + */ + short TIME_HI_AND_VERSION_BYTE_6 = 6; + /** + * Byte position of the clock sequence and reserved field + */ + short CLOCK_SEQ_HI_AND_RESERVED_BYTE_8 = 8; + + /** + * XXX added by stefan@apache.org: + * hexdigits for converting numerics to hex + */ + char[] hexDigits = "0123456789abcdef".toCharArray(); +} Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/Constants.java ------------------------------------------------------------------------------ svn = Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/Constants.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/UUID.java URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/UUID.java?rev=180346&view=auto ============================================================================== --- incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/UUID.java (added) +++ incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/UUID.java Mon Jun 6 10:36:09 2005 @@ -0,0 +1,511 @@ +/* + * Copyright 2004-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed 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.util.uuid; + +import java.io.DataInput; +import java.io.IOException; +import java.io.Serializable; +import java.util.StringTokenizer; + +/** XXX begin modification by stefan@apache.org */ +/*import org.apache.commons.id.IdentifierUtils; +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.codec.digest.DigestUtils;*/ +/** XXX end modification by stefan@apache.org */ + +/** + *UUID represents a Universally Unique Identifier per IETF
+ * Draft specification. For more information regarding the IETF Draft UUID
+ * specification
See: http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-01.txt
+ * + *Copied from the Jakarta Commons-Id project
+ * + * todo remove and use official commons-id release as soon as it is available + */ + +public class UUID implements Constants, Serializable, Comparable { + + /** + * byte array to store 128-bits composing this UUID + */ + private byte[] rawBytes = new byte[UUID_BYTE_LENGTH]; + + /** + * Holds node identifier for this UUID + */ + private Long node = null; + + /** + * Holds timestamp for this UUID + */ + private long timestamp = -1; + + /** + * Holds the clock sequence field + */ + private Short clockSq = null; + + /** + * Holds the version field of this UUID + */ + private int version = -1; + + /** + * Holds the variant field of this UUID + */ + private int variant = -1; + + /** + * Holds the internal string value of the UUID + */ + private String stringValue = null; + + /** + * XXX begin modification by stefan@apache.org + */ + private static VersionFourGenerator versionFourGenereator = new VersionFourGenerator(); + /** XXX end modification by stefan@apache.org */ + + /** + * Constructs a nil UUID + */ + public UUID() { + super(); + } + + /** + *Constructs a UUID from a 128 bit java.math.BigInteger.
+ *Method is protected as their is no standard as to the internal representation of a UUID. + * In this case a BigInteger is used with signum always positive.
+ * + * @param bigIntValue the 128 bit BigInteger to construct this UUID from. + * @throws IllegalArgumentException argument must be 128 bit + */ + /* protected UUID(BigInteger bigIntValue) throws IllegalArgumentException { + super(); + if (bigIntValue.bitLength() > UUID.UUID_BIT_LENGTH) { + throw new IllegalArgumentException("UUID must be contructed using a 128 bit BigInteger"); + } + numberValue = bigIntValue; + } */ + + /** + *Copy constructor.
+ * + * @param copyFrom the UUID to copy to create this UUID. + */ + public UUID(UUID copyFrom) { + super(); + rawBytes = copyFrom.getRawBytes(); + } + + /** + *Constructs a UUID from a 16 byte array.
+ * + * @param byteArray the 16 byte array to construct this UUID from. + * @throws IllegalArgumentException argument must be 16 bytes + */ + public UUID(byte[] byteArray) throws IllegalArgumentException { + super(); + if (byteArray.length != UUID_BYTE_LENGTH) { + throw new IllegalArgumentException("UUID must be contructed using a 16 byte array."); + } + // UUID must be immutable so a copy is used. + System.arraycopy(byteArray, 0, rawBytes, 0, UUID_BYTE_LENGTH); + } + + /** + *Constructs a UUID from a DataInput. Note if 16 bytes are not available this method will block.
+ * + * @param input the datainput with 16 bytes to read in from. + * @throws IOException exception if there is an IO problem also argument must contain 16 bytes. + */ + public UUID(DataInput input) throws IOException { + super(); + input.readFully(rawBytes, 0, UUID_BYTE_LENGTH); + } + + /** + *Constructs a UUID from two long values in most significant byte, and least significant bytes order.
+ * + * @param mostSignificant - the most significant 8 bytes of the uuid to be constructed. + * @param leastSignificant - the least significant 8 bytes of the uuid to be constructed. + */ + public UUID(long mostSignificant, long leastSignificant) { + rawBytes = Bytes.append(Bytes.toBytes(mostSignificant), Bytes.toBytes(leastSignificant)); + } + + /** XXX begin modification by stefan@apache.org */ + /** + *Constructs a UUID from a UUID formatted String.
+ * + * @param uuidString the String representing a UUID to construct this UUID + * @throws UUIDFormatException String must be a properly formatted UUID string + */ + //public UUID(String uuidString) throws UUIDFormatException { + public UUID(String uuidString) { + //Calls the copy constructor + this(UUID.fromString(uuidString)); + } + /** XXX end modification by stefan@apache.org */ + + /** XXX begin modification by stefan@apache.org */ + /** + *Parses a string for a UUID.
+ * + * @param uuidString the UUID formatted String to parse. + * XXX begin modification by stefan@apache.org + * @return Returns a UUID or null if the formatted string could not be parsed. + * @throws IllegalArgumentException the String must be a properly formatted UUID String. + * XXX end modification by stefan@apache.org + */ + //public static UUID fromString(String uuidString) throws UUIDFormatException { + public static UUID fromString(String uuidString) throws IllegalArgumentException { + String leanString = uuidString.toLowerCase(); + UUID tmpUUID = null; + + //Handle prefixed UUIDs + // e.g. urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6 + int pos = uuidString.lastIndexOf(":"); + if (pos > 1) { + leanString = uuidString.substring(++pos, uuidString.length()); + } + + //Check for 36 char length + if (leanString.length() != UUID_FORMATTED_LENGTH) { + //throw new UUIDFormatException(); + throw new IllegalArgumentException(); + } + + //Check for 5 fields + StringTokenizer tok = new StringTokenizer(leanString, "-"); + if (tok.countTokens() != TOKENS_IN_UUID) { + //throw new UUIDFormatException(); + throw new IllegalArgumentException(); + } + + //Remove the "-" from the formatted string and test token sizes + StringBuffer buf = new StringBuffer(UUID_UNFORMATTED_LENGTH); + String token = null; + int count = 0; + while (tok.hasMoreTokens()) { + token = tok.nextToken(); + if (token.length() != TOKEN_LENGTHS[count++]) { + //throw new UUIDFormatException(); + throw new IllegalArgumentException(); + } + buf.append(token); + } + + //Create from the hex value + /** XXX begin modification by stefan@apache.org */ +/* + try { + char[] chars = buf.toString().toCharArray(); + tmpUUID = new UUID(Hex.decodeHex(chars)); + } catch (DecoderException de) { + throw new UUIDFormatException(de.getMessage()); + } +*/ + String s = buf.toString(); + byte[] bytes = new byte[UUID_BYTE_LENGTH]; + for (int i = 0, j = 0; i < (UUID_BYTE_LENGTH * 2); i += 2) { + bytes[j++] = (byte) Integer.parseInt(s.substring(i, i + 2), 16); + } + tmpUUID = new UUID(bytes); + /** XXX end modification by stefan@apache.org */ + + return tmpUUID; + } + /** XXX end modification by stefan@apache.org */ + + /** + *Returns a string representation of the UUID.
+ * + * @return a string representation of the UUID formatted according to the specification. + */ + public String toString() { + //set string value if not set + if (stringValue == null) { + /** XXX begin modification by stefan@apache.org */ +/* + StringBuffer buf = new StringBuffer(new String(Hex.encodeHex(rawBytes))); + while (buf.length() != UUID_UNFORMATTED_LENGTH) { + buf.insert(0, "0"); + } + buf.ensureCapacity(UUID_FORMATTED_LENGTH); + buf.insert(FORMAT_POSITION1, '-'); + buf.insert(FORMAT_POSITION2, '-'); + buf.insert(FORMAT_POSITION3, '-'); + buf.insert(FORMAT_POSITION4, '-'); + stringValue = buf.toString(); +*/ + char[] chars = new char[UUID_FORMATTED_LENGTH]; + for (int i = 0, j = 0; i < 16; i++) { + chars[j++] = hexDigits[(rawBytes[i] >> 4) & 0x0f]; + chars[j++] = hexDigits[rawBytes[i] & 0x0f]; + if (i == 3 || i == 5 || i == 7 || i == 9) { + chars[j++] = '-'; + } + } + stringValue = new String(chars); + /** XXX end modification by stefan@apache.org */ + } + return stringValue; + } + + /** + *Returns a urn representation of the UUID. This is same as the
+ * toString() value prefixed with urn:uuid:
Compares two UUID for equality.
+ * + * @see java.lang.Object#equals(Object) + */ + + public boolean equals(Object obj) { + if (!(obj instanceof UUID)) { + return false; + } + return Bytes.areEqual(((UUID) obj).getRawBytes(), rawBytes); + } + + /** + *Returns a hash code value for the object.
+ * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + int iConstant = 37; + int iTotal = 17; + for (int i = 0; i < rawBytes.length; i++) { + iTotal = iTotal * iConstant + rawBytes[i]; + } + return iTotal; + } + + /** + *Compares two UUID's for equality
+ * + * @see Comparable#compareTo(Object) + */ + public int compareTo(Object compareTo) throws ClassCastException { + if (!(compareTo instanceof UUID)) { + throw new ClassCastException(); + } + return (Bytes.compareTo(rawBytes, ((UUID) compareTo).getRawBytes())); + } + + /** + *Returns the clock sequence value in the UUID. The clock sequence is a random assigned to a particular clock instance that + * generated the time in the timestamp of a time based UUID.
+ * + * @return the clock sequence value in the UUID. + * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. + */ + public int clockSequence() throws UnsupportedOperationException { + //if variant is not mealling leach salz throw unsupported operation exception + if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { + throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); + } + if (clockSq == null) { + byte[] b = {((byte) (rawBytes[8] & 0x3F)), rawBytes[9]}; + clockSq = new Short(Bytes.toShort(b)); + } + return clockSq.intValue(); + } + + /** + *Returns the version of the UUID. + *
Returns the variant field of the UUID.
+ * + * @return Returns the variant field of the UUID. + * @see UUID#VARIANT_NCS_COMPAT + * @see UUID#VARIANT_IETF_DRAFT + * @see UUID#VARIANT_MS + * @see UUID#VARIANT_FUTURE + */ + public int variant() { + if (variant == -1) { + if ((rawBytes[8] & 0x80) == 0x0) { + variant = VARIANT_NCS_COMPAT; + } else if ((rawBytes[8] & 0x40) == 0x0) { + variant = VARIANT_IETF_DRAFT; + } else if ((rawBytes[8] & 0x20) == 0x0) { + variant = VARIANT_MS; + } else { + variant = VARIANT_FUTURE; + } + } + return variant; + } + + /** + *Returns the node identifier found in this UUID. The specification was written such that this value holds the IEEE 802 MAC + * address. The specification permits this value to be calculated from other sources other than the MAC.
+ * + * @return the node identifier found in this UUID. + * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. + */ + public long node() throws UnsupportedOperationException { + //if variant is not mealling leach salz throw unsupported operation exception + if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { + throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); + } + if (node == null) { + byte[] b = new byte[8]; + System.arraycopy(rawBytes, 10, b, 2, 6); + node = new Long((Bytes.toLong(b) & 0xFFFFFFFFFFFFL)); + } + return node.longValue(); + } + + /** + *Returns the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset (00:00:00.00, 15 + * October 1582 ).
+ * + * @return the timestamp value of the UUID as 100-nano second intervals since the Gregorian change offset. + * @throws UnsupportedOperationException thrown if this is not a IETF variant or not a time-based UUID. + */ + public long timestamp() throws UnsupportedOperationException { + //if variant is not mealling leach salz throw unsupported operation exception + if (variant() != VARIANT_IETF_DRAFT || version() != VERSION_ONE) { + throw new UnsupportedOperationException(WRONG_VAR_VER_MSG); + } + if (timestamp == -1) { + byte[] longVal = new byte[8]; + System.arraycopy(rawBytes, TIME_HI_START_POS, longVal, TIME_HI_TS_POS, TIME_HI_BYTE_LEN); + System.arraycopy(rawBytes, TIME_MID_START_POS, longVal, TIME_MID_TS_POS, TIME_MID_BYTE_LEN); + System.arraycopy(rawBytes, TIME_LOW_START_POS, longVal, TIME_LOW_TS_POS, TIME_LOW_BYTE_LEN); + longVal[TIME_HI_TS_POS] &= 0x0F; + timestamp = Bytes.toLong(longVal); + } + return timestamp; + } + + /** + *Returns the least significant bits stored in the uuid's internal structure.
+ * + * @return the least significant bits stored in the uuid's internal structure. + */ + long getLeastSignificantBits() { + byte[] lsb = new byte[8]; + System.arraycopy(rawBytes, 8, lsb, 0, 8); + return Bytes.toLong(lsb); + } + + /** + *Returns the least significant bits stored in the uuid's internal structure.
+ * + * @return the least significant bits stored in the uuid's internal structure. + */ + long getMostSignificantBits() { + byte[] msb = new byte[8]; + System.arraycopy(rawBytes, 0, msb, 0, 8); + return Bytes.toLong(msb); + } + + /** + *Returns a copy of the byte values contained in this UUID. + * + * @return a copy of the byte values contained in this UUID. + */ + public byte[] getRawBytes() { + byte[] ret = new byte[UUID_BYTE_LENGTH]; + System.arraycopy(rawBytes, 0, ret, 0, UUID_BYTE_LENGTH); + return ret; + } + + /** + *
Returns a new version 4 UUID, based upon Random bits.
+ * + * @return a new version 4 UUID, based upon Random bits. + */ + /** + * XXX begin modification by stefan@apache.org + */ + //static UUID randomUUID() { + public static UUID randomUUID() { + //return (UUID) IdentifierUtils.UUID_VERSION_FOUR_GENERATOR.nextIdentifier(); + return (UUID) versionFourGenereator.nextIdentifier(); + } + /** XXX end modification by stefan@apache.org */ + + /** XXX begin modification by stefan@apache.org */ + /** + *Returns a new version 1 UUID, based upon node identifier and time stamp.
+ * + * @return a new version 1 UUID, based upon node identifier and time stamp. + */ +/* static UUID timeUUID() { + return (UUID) IdentifierUtils.UUID_VERSION_ONE_GENERATOR.nextIdentifier(); + }*/ + /** XXX end modification by stefan@apache.org */ + + /** XXX begin modification by stefan@apache.org */ + /** + *Returns a new version three UUID given a name and the namespace's UUID.
+ * + * @param name String the name to calculate the UUID for. + * @param namespace UUID assigned to this namespace. + * @return a new version three UUID given a name and the namespace's UUID. + */ +/* static UUID nameUUIDFromString(String name, UUID namespace) { + byte[] nameAsBytes = name.getBytes(); + byte[] concat = new byte[UUID_BYTE_LENGTH + nameAsBytes.length]; + System.arraycopy(namespace.getRawBytes(), 0, concat, 0, UUID_BYTE_LENGTH); + System.arraycopy(nameAsBytes, 0, concat, UUID_BYTE_LENGTH, nameAsBytes.length); + byte[] raw = DigestUtils.md5(concat); + //Set version + raw[TIME_HI_AND_VERSION_BYTE_6] &= 0x0F; + raw[TIME_HI_AND_VERSION_BYTE_6] |= (UUID.VERSION_THREE << 4); + //Set variant + raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] &= 0x3F; //0011 1111 + raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] |= 0x80; //1000 0000 + + return new UUID(raw); + }*/ + /** XXX end modification by stefan@apache.org */ +} Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/UUID.java ------------------------------------------------------------------------------ svn = Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/UUID.java ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/VersionFourGenerator.java URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/VersionFourGenerator.java?rev=180346&view=auto ============================================================================== --- incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/VersionFourGenerator.java (added) +++ incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/VersionFourGenerator.java Mon Jun 6 10:36:09 2005 @@ -0,0 +1,168 @@ +/* + * Copyright 2004-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed 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.util.uuid; + +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.util.Random; + +/** XXX begin modification by stefan@apache.org */ +//import org.apache.commons.id.IdentifierGenerator; +/** XXX end modification by stefan@apache.org */ + +/** + *Class is responsible for generating version 4 UUID's per the IETF draft
+ * specification. This class attempts to use a java.security.SecureRandom with
+ * the following instantiation
+ * SecureRandom.getInstance("SHA1PRNG", "SUN"). If neither secure
+ * random implementation is avialable or an Exception is raised a java.util.Random
+ * is used.
Note: Instantiation of SecureRandom is an expensive operation. The + * constructor therefore creates a static member to hold the SecureRandom. + * The first call to getInstance may take time; subsequent calls should return + * quickly.
+ * + *Copied from the Jakarta Commons-Id project
+ * + * todo remove and use official commons-id release as soon as it is available + * + * + */ + +/** + * XXX begin modification by stefan@apache.org + */ +//public final class VersionFourGenerator implements IdentifierGenerator, QueryConstants { +public final class VersionFourGenerator implements Constants { + /** XXX end modification by stefan@apache.org */ + + /** + * Random used to generate UUID's + */ + private static final Random regularRandom = new Random(); + + /** + * SecureRandom used to generate UUID's + */ + private static Random secureRandom; + + /** + * The pseudo-random number generator to use + */ + private static String usePRNG = "SHA1PRNG"; + + /** + * The pseudo-random number generator package name to use + */ + private static String usePRNGPackage = "SUN"; + + /** + *Constructs a new VersionFourGenerator.
+ */ + public VersionFourGenerator() { + super(); + } + + /** + *Returns a new version four UUID.
+ * + * @return Object a new version 4 UUID. + */ + public Object nextIdentifier() { + return nextUUID(false); + } + + /** + *Returns a new version four UUID.
+ *This overloaded method may produce both UUID's using a SecureRandom as well as using normal
+ * Random
+ *
SecureRandom in generating the random bits.
+ * @return a new version four UUID that was generated by either a Random or SecureRandom.
+ */
+ public Object nextIdentifier(boolean secure) {
+ if (secure) {
+ return nextUUID(true);
+ }
+ return nextUUID(false);
+ }
+
+ /**
+ * Returns a new version four UUID.
+ * + * @return Object a new version 4 UUID. + */ + private UUID nextUUID() { + //Call nextUUID with secure = false + return nextUUID(false); + } + + /** + *Returns a new version four UUID using either SecureRandom or Random.
SecureRandom or Random.
+ * @return a new version four UUID using either SecureRandom or Random.
+ */
+ private UUID nextUUID(boolean secure) {
+ byte[] raw = new byte[UUID_BYTE_LENGTH];
+ if (secure) {
+ //Initialize the secure random if null.
+ if (secureRandom == null) {
+ try {
+ if (usePRNGPackage != null) {
+ secureRandom = SecureRandom.getInstance(usePRNG, usePRNGPackage);
+ } else {
+ secureRandom = SecureRandom.getInstance(usePRNG);
+ }
+ } catch (NoSuchAlgorithmException nsae) {
+ secure = false; //Fail back to default PRNG/Random
+ } catch (NoSuchProviderException nspe) {
+ secure = false; //Fail back to default PRNG/Random
+ }
+ secureRandom.nextBytes(raw);
+ }
+ }
+
+ if (!secure) {
+ regularRandom.nextBytes(raw);
+ }
+
+ raw[TIME_HI_AND_VERSION_BYTE_6] &= 0x0F;
+ raw[TIME_HI_AND_VERSION_BYTE_6] |= (UUID.VERSION_FOUR << 4);
+
+ raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] &= 0x3F; //0011 1111
+ raw[CLOCK_SEQ_HI_AND_RESERVED_BYTE_8] |= 0x80; //1000 0000
+
+ return new UUID(raw);
+ }
+
+ /**
+ * Allows clients to set the pseudo-random number generator implementation used when generating a version four uuid with
+ * the secure option. The secure option uses a SecureRandom. The packageName string may be null to specify
+ * no preferred package.
+
+ This package contains a UUID (Universally Unique Identifier) version 4 + generator implementation copied from from the + + Jakarta Commons-Id project. +
++ TODO: Replace with commons-id.jar as soon as official release is + available. +
+ + \ No newline at end of file Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/util/uuid/package.html ------------------------------------------------------------------------------ svn:eol-style = native Added: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/value/ValueHelper.java URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/value/ValueHelper.java?rev=180346&view=auto ============================================================================== --- incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/value/ValueHelper.java (added) +++ incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/value/ValueHelper.java Mon Jun 6 10:36:09 2005 @@ -0,0 +1,208 @@ +/* + * Copyright 2004-2005 The Apache Software Foundation or its licensors, + * as applicable. + * + * Licensed 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.value; + +import org.apache.jackrabbit.util.Base64; +import org.apache.jackrabbit.util.Text; + +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; +import javax.jcr.Value; +import javax.jcr.ValueFormatException; +import javax.jcr.ValueFactory; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringWriter; +import java.io.Writer; +import java.io.ByteArrayInputStream; + +/** + * TheValueHelper class provides several Value
+ * related utility methods.
+ */
+public class ValueHelper {
+
+ /**
+ * Empty private constructor (avoid instanciation).
+ */
+ private ValueHelper() {
+ }
+
+ /**
+ * Serializes the given value to a String. The serialization
+ * format is the same as used by Document & System View XML, i.e.
+ * binary values will be Base64-encoded whereas for all others
+ * {@link javax.jcr.Value#getString()} will be used.
+ *
+ * @param value the value to be serialized
+ * @param encodeBlanks if true space characters will be encoded
+ * as "_x0020_" within he output string.
+ * @return a string representation of the given value.
+ * @throws IllegalStateException if the given value is in an illegal state
+ * @throws RepositoryException if an error occured during the serialization.
+ */
+ public static String serialize(Value value, boolean encodeBlanks)
+ throws IllegalStateException, RepositoryException {
+ StringWriter writer = new StringWriter();
+ try {
+ serialize(value, encodeBlanks, writer);
+ } catch (IOException ioe) {
+ throw new RepositoryException("failed to serialize value",
+ ioe);
+ }
+ return writer.toString();
+ }
+
+ /**
+ * Outputs the serialized value to a Writer. The serialization
+ * format is the same as used by Document & System View XML, i.e.
+ * binary values will be Base64-encoded whereas for all others
+ * {@link javax.jcr.Value#getString()} will be used for
+ * serialization.
+ *
+ * @param value the value to be serialized
+ * @param encodeBlanks if true space characters will be encoded
+ * as "_x0020_" within he output string.
+ * @param writer writer to output the encoded data
+ * @throws IllegalStateException if the given value is in an illegal state
+ * @throws IOException if an i/o error occured during the
+ * serialization
+ * @throws RepositoryException if an error occured during the serialization.
+ */
+ public static void serialize(Value value, boolean encodeBlanks,
+ Writer writer)
+ throws IllegalStateException, IOException, RepositoryException {
+ if (value.getType() == PropertyType.BINARY) {
+ // binary data, base64 encoding required;
+ // the encodeBlanks flag can be ignored since base64-encoded
+ // data cannot contain space characters
+ InputStream in = value.getStream();
+ try {
+ Base64.encode(in, writer);
+ // no need to close StringWriter
+ //writer.close();
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ } else {
+ String textVal = value.getString();
+ if (encodeBlanks) {
+ // enocde blanks in string
+ textVal = Text.replace(textVal, " ", "_x0020_");
+ }
+ writer.write(textVal);
+ }
+ }
+
+ /**
+ * Deserializes the given string to a Value of the given type.
+ *
+ * @param factory the factory used to create the {@link Value} object of the
+ * specified type.
+ * @param value string to be deserialized
+ * @param type type of value
+ * @param decodeBlanks if true "_x0020_" character
+ * sequences will be decoded to single space characters each.
+ * @return the deserialized Value
+ * @throws ValueFormatException if the string data is not of the required
+ * format
+ * @throws RepositoryException if an error occured during the deserialization.
+ */
+ public static Value deserialize(ValueFactory factory, String value, int type,
+ boolean decodeBlanks)
+ throws ValueFormatException, RepositoryException {
+ if (type == PropertyType.BINARY) {
+ // base64 encoded binary value;
+ // the encodeBlanks flag can be ignored since base64-encoded
+ // data cannot contain encoded space characters
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ Base64.decode(value, baos);
+ // no need to close ByteArrayOutputStream
+ //baos.close();
+ } catch (IOException ioe) {
+ throw new RepositoryException("failed to decode binary value",
+ ioe);
+ }
+ return factory.createValue(new ByteArrayInputStream(baos.toByteArray()));
+ } else {
+ if (decodeBlanks) {
+ // decode encoded blanks in value
+ value = Text.replace(value, "_x0020_", " ");
+ }
+ return factory.createValue(value, type);
+ }
+ }
+
+ /**
+ * Deserializes the string data read from the given reader to a
+ * Value of the given type.
+ *
+ * @param factory the factory used to create the {@link Value} object of the
+ * specified type.
+ * @param reader reader for the string data to be deserialized
+ * @param type type of value
+ * @param decodeBlanks if true "_x0020_" character
+ * sequences will be decoded to single space characters each.
+ * @return the deserialized Value
+ * @throws IOException if an i/o error occured during the serialization
+ * @throws ValueFormatException if the string data is not of the required
+ * format
+ * @throws RepositoryException if an error occured during the deserialization.
+ */
+ public static Value deserialize(ValueFactory factory, Reader reader, int type,
+ boolean decodeBlanks)
+ throws IOException, ValueFormatException, RepositoryException {
+ if (type == PropertyType.BINARY) {
+ // base64 encoded binary value;
+ // the encodeBlanks flag can be ignored since base64-encoded
+ // data cannot contain encoded space characters
+/*
+ // @todo decode to temp file and pass FileInputStream to BinaryValue constructor
+ File tmpFile = File.createTempFile("bin", null);
+ FileOutputStream out = new FileOutputStream(tmpFile);
+ tmpFile.deleteOnExit();
+ Base64.decode(reader, out);
+ out.close();
+ return new BinaryValue(new FileInputStream(tmpFile));
+*/
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Base64.decode(reader, baos);
+ // no need to close ByteArrayOutputStream
+ return factory.createValue(new ByteArrayInputStream(baos.toByteArray()));
+ } else {
+ char[] chunk = new char[8192];
+ int read;
+ StringBuffer buf = new StringBuffer();
+ while ((read = reader.read(chunk)) > -1) {
+ buf.append(chunk, 0, read);
+ }
+ String value = buf.toString();
+ if (decodeBlanks) {
+ // decode encoded blanks in value
+ value = Text.replace(value, "_x0020_", " ");
+ }
+ return factory.createValue(value, type);
+ }
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/value/ValueHelper.java
------------------------------------------------------------------------------
svn =
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/commons/src/java/org/apache/jackrabbit/value/ValueHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/jackrabbit/trunk/contrib/jcr-server/project.properties
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/project.properties?rev=180346&r1=180345&r2=180346&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/project.properties (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/project.properties Mon Jun 6 10:36:09 2005
@@ -1,2 +1,7 @@
maven.javadoc.links=http://java.sun.com/j2se/1.4.2/docs/api/,http://www.day.com/maven/jsr170/javadocs/jcr-0.16.1-pfd/
maven.repo.remote = http://www.ibiblio.org/maven/,http://www.day.com/maven/
+
+#-------------------------------------------------------
+jackrabbit.build.version.jcr=1.0
+jackrabbit.build.version.jackrabbit=0.16.4.1-dev
+jackrabbit.build.version.jcr.rmi=0.16.4.1
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Jun 6 10:36:09 2005
@@ -1 +1,2 @@
target
+*.iml
Modified: incubator/jackrabbit/trunk/contrib/jcr-server/server/project.xml
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/project.xml?rev=180346&r1=180345&r2=180346&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/project.xml (original)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/project.xml Mon Jun 6 10:36:09 2005
@@ -29,29 +29,26 @@
AbstractWebdavServlet
- *
- * todo respect Position header
+ *
+ * todo respect Position header
*/
abstract public class AbstractWebdavServlet extends HttpServlet implements DavConstants {
- /** default logger */
+ /**
+ * default logger
+ */
private static Logger log = Logger.getLogger(AbstractWebdavServlet.class);
/**
- * Create a new DavResource
+ * Default value for the 'WWW-Authenticate' header, that is set, if request
+ * results in a {@link DavServletResponse#SC_UNAUTHORIZED 401 (Unauthorized)}
+ * error.
+ *
+ * @see #getAuthenticateHeaderValue()
+ */
+ public static final String DEFAULT_AUTHENTICATE_HEADER = "Basic Realm=Jackrabbit Webdav Server";
+
+ /**
+ * Checks if the precondition for this request and resource is valid.
+ *
+ * @param request
+ * @param resource
+ * @return
+ */
+ abstract protected boolean isPreconditionValid(WebdavRequest request, DavResource resource);
+
+ /**
+ * Returns the DavSessionProvider.
+ *
+ * @return the session provider
+ */
+ abstract public DavSessionProvider getSessionProvider();
+
+ /**
+ * Returns the DavLocatorFactory.
+ *
+ * @return the locator factory
+ */
+ abstract public DavLocatorFactory getLocatorFactory();
+
+ /**
+ * Returns the DavResourceFactory.
+ *
+ * @return the resource factory
+ */
+ abstract public DavResourceFactory getResourceFactory();
+
+ /**
+ * Returns the value of the 'WWW-Authenticate' header, that is returned in
+ * case of 401 error.
+ *
+ * @return value of the 'WWW-Authenticate' header
+ */
+ abstract public String getAuthenticateHeaderValue();
+
+ /**
+ * Service the given request.
*
- * @param locator
* @param request
* @param response
- * @return resource for the given locator
- * @throws DavException
+ * @throws ServletException
+ * @throws IOException
*/
- abstract protected DavResource createResource(DavResourceLocator locator,
- WebdavRequest request,
- WebdavResponse response) throws DavException;
+ protected void service(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+
+ WebdavRequest webdavRequest = new WebdavRequestImpl(request, getLocatorFactory());
+ WebdavResponse webdavResponse = new WebdavResponseImpl(response);
+ try {
+ // make sure there is a authenticated user
+ if (!getSessionProvider().attachSession(webdavRequest)) {
+ return;
+ }
+
+ // check matching if=header for lock-token relevant operations
+ DavResource resource = getResourceFactory().createResource(webdavRequest.getRequestLocator(), webdavRequest, webdavResponse);
+ if (!isPreconditionValid(webdavRequest, resource)) {
+ webdavResponse.sendError(DavServletResponse.SC_PRECONDITION_FAILED);
+ return;
+ }
+
+ int methodCode = DavMethods.getMethodCode(webdavRequest.getMethod());
+ if (!execute(webdavRequest, webdavResponse, methodCode, resource)) {
+ super.service(request, response);
+ }
+
+ } catch (DavException e) {
+ if (e.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED) {
+ webdavResponse.setHeader("WWW-Authenticate", getAuthenticateHeaderValue());
+ webdavResponse.sendError(e.getErrorCode(), e.getStatusPhrase());
+ } else {
+ webdavResponse.sendErrorResponse(e);
+ }
+ } finally {
+ getSessionProvider().releaseSession(webdavRequest);
+ }
+ }
+
+ /**
+ * Executes the respective method in the given webdav context
+ *
+ * @param request
+ * @param response
+ * @param method
+ * @param resource
+ * @throws ServletException
+ * @throws IOException
+ * @throws DavException
+ */
+ protected boolean execute(WebdavRequest request, WebdavResponse response,
+ int method, DavResource resource)
+ throws ServletException, IOException, DavException {
+
+ switch (method) {
+ case DavMethods.DAV_GET:
+ doGet(request, response, resource);
+ break;
+ case DavMethods.DAV_HEAD:
+ doHead(request, response, resource);
+ break;
+ case DavMethods.DAV_PROPFIND:
+ doPropFind(request, response, resource);
+ break;
+ case DavMethods.DAV_PROPPATCH:
+ doPropPatch(request, response, resource);
+ break;
+ case DavMethods.DAV_POST:
+ doPost(request, response, resource);
+ break;
+ case DavMethods.DAV_PUT:
+ doPut(request, response, resource);
+ break;
+ case DavMethods.DAV_DELETE:
+ doDelete(request, response, resource);
+ break;
+ case DavMethods.DAV_COPY:
+ doCopy(request, response, resource);
+ break;
+ case DavMethods.DAV_MOVE:
+ doMove(request, response, resource);
+ break;
+ case DavMethods.DAV_MKCOL:
+ doMkCol(request, response, resource);
+ break;
+ case DavMethods.DAV_OPTIONS:
+ doOptions(request, response, resource);
+ break;
+ case DavMethods.DAV_LOCK:
+ doLock(request, response, resource);
+ break;
+ case DavMethods.DAV_UNLOCK:
+ doUnlock(request, response, resource);
+ break;
+ case DavMethods.DAV_ORDERPATCH:
+ doOrderPatch(request, response, resource);
+ break;
+ case DavMethods.DAV_SUBSCRIBE:
+ doSubscribe(request, response, resource);
+ break;
+ case DavMethods.DAV_UNSUBSCRIBE:
+ doUnsubscribe(request, response, resource);
+ break;
+ case DavMethods.DAV_POLL:
+ doPoll(request, response, resource);
+ break;
+ case DavMethods.DAV_SEARCH:
+ doSearch(request, response, resource);
+ break;
+ case DavMethods.DAV_VERSION_CONTROL:
+ doVersionControl(request, response, resource);
+ break;
+ case DavMethods.DAV_LABEL:
+ doLabel(request, response, resource);
+ break;
+ case DavMethods.DAV_REPORT:
+ doReport(request, response, resource);
+ break;
+ case DavMethods.DAV_CHECKIN:
+ doCheckin(request, response, resource);
+ break;
+ case DavMethods.DAV_CHECKOUT:
+ doCheckout(request, response, resource);
+ break;
+ case DavMethods.DAV_UNCHECKOUT:
+ doUncheckout(request, response, resource);
+ break;
+ case DavMethods.DAV_MERGE:
+ doMerge(request, response, resource);
+ break;
+ case DavMethods.DAV_UPDATE:
+ doUpdate(request, response, resource);
+ break;
+ case DavMethods.DAV_MKWORKSPACE:
+ doMkWorkspace(request, response, resource);
+ break;
+ default:
+ // any other method
+ return false;
+ }
+ return true;
+ }
/**
* The OPTION method
@@ -82,7 +291,7 @@
response.addHeader("Allow", resource.getSupportedMethods());
response.addHeader("MS-Author-Via", DavConstants.HEADER_DAV);
if (resource instanceof SearchResource) {
- String[] langs = ((SearchResource)resource).getQueryGrammerSet().getQueryLanguages();
+ String[] langs = ((SearchResource) resource).getQueryGrammerSet().getQueryLanguages();
for (int i = 0; i < langs.length; i++) {
response.addHeader(SearchConstants.HEADER_DASL, "<" + langs[i] + ">");
}
@@ -91,7 +300,7 @@
OptionsResponse oR = null;
OptionsInfo oInfo = request.getOptionsInfo();
if (oInfo != null && resource instanceof DeltaVResource) {
- oR = ((DeltaVResource)resource).getOptionResponse(oInfo);
+ oR = ((DeltaVResource) resource).getOptionResponse(oInfo);
}
if (oR == null) {
response.setStatus(DavServletResponse.SC_OK);
@@ -168,7 +377,7 @@
DavProperty contentLength = resource.getProperty(DavPropertyName.GETCONTENTLENGTH);
if (contentLength != null) {
try {
- int length = Integer.parseInt(contentLength.getValue()+"");
+ int length = Integer.parseInt(contentLength.getValue() + "");
if (length > 0) {
response.setIntHeader("Content-Length", length);
}
@@ -178,16 +387,26 @@
}
// spool content in case of 'GET' request
- if (sendContent) {
- InputStream in = resource.getStream();
+ InputStream in = resource.getStream();
+ try {
+ if (sendContent) {
+ if (in != null) {
+ OutputStream out = response.getOutputStream();
+ byte[] buffer = new byte[8192];
+ int read;
+ while ((read = in.read(buffer)) >= 0) {
+ out.write(buffer, 0, read);
+ }
+ }
+ }
+ } finally {
+ // also close stream if not sending content
if (in != null) {
- OutputStream out = response.getOutputStream();
- byte[] buffer = new byte[8192];
- int read;
- while ((read = in.read(buffer)) >= 0 ) {
- out.write(buffer, 0, read);
+ try {
+ in.close();
+ } catch (IOException e) {
+ // ignore
}
- in.close();
}
}
response.flushBuffer();
@@ -241,7 +460,7 @@
// TODO: not correct resolution of merge conflicts are immediately perstisted
// TODO: rfc 2518 requires, that no changes must only be persisted if the complete proppatch-req succeeds
if (resource instanceof VersionControlledResource) {
- ((VersionControlledResource)resource).resolveMergeConflict(setProperties, removeProperties);
+ ((VersionControlledResource) resource).resolveMergeConflict(setProperties, removeProperties);
}
// complete any other property setting or removing
@@ -261,6 +480,20 @@
}
/**
+ * The POST method. Delegate to PUT
+ *
+ * @param request
+ * @param response
+ * @param resource
+ * @throws IOException
+ * @throws DavException
+ */
+ protected void doPost(WebdavRequest request, WebdavResponse response,
+ DavResource resource) throws IOException, DavException {
+ doPut(request, response, resource);
+ }
+
+ /**
* The PUT method
*
* @param request
@@ -281,7 +514,7 @@
int status;
// test if resource already exists
- if (resource.exists()){
+ if (resource.exists()) {
status = DavServletResponse.SC_NO_CONTENT;
} else {
status = DavServletResponse.SC_CREATED;
@@ -357,7 +590,7 @@
return;
}
- DavResource destResource = createResource(request.getDestinationLocator(), request, response);
+ DavResource destResource = getResourceFactory().createResource(request.getDestinationLocator(), request, response);
int status = validateDestination(destResource, request);
if (status > DavServletResponse.SC_NO_CONTENT) {
response.sendError(status);
@@ -380,7 +613,7 @@
protected void doMove(WebdavRequest request, WebdavResponse response,
DavResource resource) throws IOException, DavException {
- DavResource destResource = createResource(request.getDestinationLocator(), request, response);
+ DavResource destResource = getResourceFactory().createResource(request.getDestinationLocator(), request, response);
int status = validateDestination(destResource, request);
if (status > DavServletResponse.SC_NO_CONTENT) {
response.sendError(status);
@@ -390,7 +623,7 @@
resource.move(destResource);
response.setStatus(status);
}
-
+
/**
* Validate the given destination resource and return the proper status
* code: Any return value greater/equal than {@link DavServletResponse#SC_NO_CONTENT}
@@ -401,10 +634,10 @@
* @return status code indicating whether the destination is valid.
*/
private int validateDestination(DavResource destResource, WebdavRequest request)
- throws DavException {
+ throws DavException {
String destHeader = request.getHeader(HEADER_DESTINATION);
- if (destHeader == null || "".equals(destHeader)){
+ if (destHeader == null || "".equals(destHeader)) {
return DavServletResponse.SC_BAD_REQUEST;
}
if (destResource.getLocator().equals(request.getRequestLocator())) {
@@ -419,7 +652,7 @@
return DavServletResponse.SC_PRECONDITION_FAILED;
} else {
// overwrite existing resource
- destResource.getCollection().removeMember(destResource);
+ destResource.getCollection().removeMember(destResource);
status = DavServletResponse.SC_NO_CONTENT;
}
} else {
@@ -489,7 +722,7 @@
String lockToken = request.getLockToken();
TransactionInfo tInfo = request.getTransactionInfo();
if (tInfo != null) {
- ((TransactionResource)resource).unlock(lockToken, tInfo);
+ ((TransactionResource) resource).unlock(lockToken, tInfo);
} else {
resource.unlock(lockToken);
}
@@ -521,7 +754,7 @@
return;
}
// perform reordering of internal members
- ((OrderingResource)resource).orderMembers(op);
+ ((OrderingResource) resource).orderMembers(op);
response.setStatus(DavServletResponse.SC_OK);
//TODO: in case of failure Multistatus is required...
@@ -551,7 +784,7 @@
response.sendError(DavServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
return;
}
- Subscription subs = ((ObservationResource)resource).subscribe(info, request.getSubscriptionId());
+ Subscription subs = ((ObservationResource) resource).subscribe(info, request.getSubscriptionId());
response.sendSubscriptionResponse(subs);
}
@@ -573,7 +806,7 @@
response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
- ((ObservationResource)resource).unsubscribe(request.getSubscriptionId());
+ ((ObservationResource) resource).unsubscribe(request.getSubscriptionId());
response.setStatus(DavServletResponse.SC_NO_CONTENT);
}
@@ -595,7 +828,7 @@
response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
- EventDiscovery ed = ((ObservationResource)resource).poll(request.getSubscriptionId());
+ EventDiscovery ed = ((ObservationResource) resource).poll(request.getSubscriptionId());
response.sendPollResponse(ed);
}
@@ -615,7 +848,7 @@
response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
- ((VersionableResource)resource).addVersionControl();
+ ((VersionableResource) resource).addVersionControl();
}
/**
@@ -633,9 +866,9 @@
LabelInfo labelInfo = request.getLabelInfo();
if (resource instanceof VersionResource) {
- ((VersionResource)resource).label(labelInfo);
+ ((VersionResource) resource).label(labelInfo);
} else if (resource instanceof VersionControlledResource) {
- ((VersionControlledResource)resource).label(labelInfo);
+ ((VersionControlledResource) resource).label(labelInfo);
} else {
// any other resource type that does not support a LABEL request
response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
@@ -659,7 +892,7 @@
return;
}
ReportInfo info = request.getReportInfo();
- Report report = ((DeltaVResource)resource).getReport(info);
+ Report report = ((DeltaVResource) resource).getReport(info);
response.sendXmlResponse(report.toXml(), DavServletResponse.SC_OK);
}
@@ -680,7 +913,7 @@
response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
- String versionHref = ((VersionControlledResource)resource).checkin();
+ String versionHref = ((VersionControlledResource) resource).checkin();
response.setHeader(DeltaVConstants.HEADER_LOCATION, versionHref);
}
@@ -700,7 +933,7 @@
response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
- ((VersionControlledResource)resource).checkout();
+ ((VersionControlledResource) resource).checkout();
}
/**
@@ -713,13 +946,13 @@
* @throws IOException
*/
protected void doUncheckout(WebdavRequest request, WebdavResponse response,
- DavResource resource)
+ DavResource resource)
throws DavException, IOException {
if (!(resource instanceof VersionControlledResource)) {
response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
- ((VersionControlledResource)resource).uncheckout();
+ ((VersionControlledResource) resource).uncheckout();
}
/**
@@ -734,12 +967,12 @@
protected void doMerge(WebdavRequest request, WebdavResponse response,
DavResource resource) throws DavException, IOException {
- if (!(resource instanceof VersionControlledResource)) {
+ if (!(resource instanceof VersionControlledResource)) {
response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
MergeInfo info = request.getMergeInfo();
- MultiStatus ms = ((VersionControlledResource)resource).merge(info);
+ MultiStatus ms = ((VersionControlledResource) resource).merge(info);
response.sendMultiStatusResponse(ms);
}
@@ -760,7 +993,7 @@
return;
}
UpdateInfo info = request.getUpdateInfo();
- MultiStatus ms = ((VersionControlledResource)resource).update(info);
+ MultiStatus ms = ((VersionControlledResource) resource).update(info);
response.sendMultiStatusResponse(ms);
}
@@ -774,7 +1007,7 @@
* @throws IOException
*/
protected void doMkWorkspace(WebdavRequest request, WebdavResponse response,
- DavResource resource) throws DavException, IOException {
+ DavResource resource) throws DavException, IOException {
if (resource.exists()) {
log.warn("Cannot create a new workspace. Resource already exists.");
response.sendError(DavServletResponse.SC_FORBIDDEN);
@@ -791,13 +1024,13 @@
response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
return;
}
- ((DeltaVResource)parentResource).addWorkspace(resource);
+ ((DeltaVResource) parentResource).addWorkspace(resource);
response.setStatus(DavServletResponse.SC_CREATED);
}
/**
* The SEARCH method
- *
+ *
* @param request
* @param response
* @param resource
@@ -815,11 +1048,11 @@
Document doc = request.getRequestDocument();
if (doc != null) {
SearchInfo sR = new SearchInfo(doc);
- response.sendMultiStatusResponse(((SearchResource)resource).search(sR));
+ response.sendMultiStatusResponse(((SearchResource) resource).search(sR));
} else {
// request without request body is valid if requested resource
// is a 'query' resource.
- response.sendMultiStatusResponse(((SearchResource)resource).search(null));
+ response.sendMultiStatusResponse(((SearchResource) resource).search(null));
}
} catch (IllegalArgumentException e) {
response.sendError(DavServletResponse.SC_BAD_REQUEST);
Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/CredentialsProvider.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/CredentialsProvider.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/CredentialsProvider.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/CredentialsProvider.java Mon Jun 6 10:36:09 2005
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed 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.server;
+
+import javax.jcr.Credentials;
+import javax.jcr.LoginException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.ServletException;
+
+/**
+ * This Interface defines a provider for the credentials.
+ */
+public interface CredentialsProvider {
+
+ /**
+ * Extracts the credentials from the given servlet request.
+ *
+ * @param request
+ * @return the credentials or null
+ * @throws LoginException if the credentials are invalid
+ * @throws ServletException if an error occurrs
+ */
+ public Credentials getCredentials(HttpServletRequest request)
+ throws LoginException, ServletException;
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/CredentialsProvider.java
------------------------------------------------------------------------------
svn =
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/CredentialsProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java Mon Jun 6 10:36:09 2005
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed 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.server;
+
+import javax.jcr.LoginException;
+import javax.jcr.Session;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * This Interface defines a provider for repository sessions
+ */
+public interface SessionProvider {
+
+ /**
+ * Provides the repository session suitable for the given request.
+ *
+ * @param request
+ * @param rep the repository to login
+ * @param workspace the workspace name
+ * @return the session or null
+ * @throws LoginException if the credentials are invalid
+ * @throws ServletException if an error occurrs
+ */
+ public Session getSession(HttpServletRequest request, Repository rep, String workspace)
+ throws LoginException, ServletException, RepositoryException;
+
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java
------------------------------------------------------------------------------
svn =
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java Mon Jun 6 10:36:09 2005
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed 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.server;
+
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.jcr.LoginException;
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.ServletException;
+
+/**
+ * This Class implements a default session provider uses a credentials provider.
+ */
+public class SessionProviderImpl implements SessionProvider {
+
+ /**
+ * the credentials provider
+ */
+ private CredentialsProvider cp;
+
+ /**
+ * Creates a new SessionProvider
+ * @param cp
+ */
+ public SessionProviderImpl(CredentialsProvider cp) {
+ this.cp = cp;
+ }
+
+ /**
+ * {@inheritDoc }
+ */
+ public Session getSession(HttpServletRequest request, Repository repository,
+ String workspace)
+ throws LoginException, RepositoryException, ServletException {
+ Credentials creds = cp.getCredentials(request);
+ return repository.login(creds, workspace);
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java
------------------------------------------------------------------------------
svn =
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/SessionProviderImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractCommand.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractCommand.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractCommand.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractCommand.java Mon Jun 6 10:36:09 2005
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed 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.server.io;
+
+import org.apache.commons.chain.Command;
+import org.apache.commons.chain.Context;
+import org.apache.jackrabbit.JcrConstants;
+
+/**
+ * This Class implements an abstract command
+ */
+public abstract class AbstractCommand implements Command, JcrConstants {
+
+ /**
+ * the id of the command
+ */
+ private String id;
+
+ /**
+ * flag, indicating if this command is enabled
+ */
+ private boolean enabled = true;
+
+ /**
+ * Executes this command by calling {@link #execute(AbstractContext)} if
+ * this command is not disabled by the context properties.
+ *
+ * @param context the (import) context.
+ * @return the return value of the delegated method or false;
+ * @throws Exception in an error occurrs
+ */
+ final public boolean execute(Context context) throws Exception {
+ if (context instanceof AbstractContext) {
+ AbstractContext ctx = (AbstractContext) context;
+ if (!ctx.isCommandEnabled(getId(), enabled)) {
+ // ignore if this command is disabled by context property
+ return false;
+ }
+ return execute(ctx);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Sets the enabled flag.
+ * @param enabled
+ */
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ /**
+ * Executes this command
+ *
+ * @param context
+ * @return
+ * @throws Exception
+ */
+ public abstract boolean execute(AbstractContext context) throws Exception;
+
+ /**
+ * Gets the id of this command
+ * @return
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Sets the id of this command
+ * @param id
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+}
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractCommand.java
------------------------------------------------------------------------------
svn =
Propchange: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractCommand.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractContext.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractContext.java?rev=180346&view=auto
==============================================================================
--- incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractContext.java (added)
+++ incubator/jackrabbit/trunk/contrib/jcr-server/server/src/java/org/apache/jackrabbit/server/io/AbstractContext.java Mon Jun 6 10:36:09 2005
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed 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.server.io;
+
+import org.apache.commons.chain.Context;
+
+import java.util.Properties;
+
+/**
+ */
+public class AbstractContext extends Properties implements Context {
+
+ /**
+ * Creates a new AbstractContext that used the given properties as default
+ * @param defaults
+ */
+ public AbstractContext(Properties defaults) {
+ super(defaults);
+ }
+
+ /**
+ * Returns the value of the property or def if the property
+ * does not exist.
+ * @param name the name of the property
+ * @param def the default value to return if the property does not exist.
+ * @return the value of the property or def
+ */
+ public String getProperty(String name, String def) {
+ String val = getProperty(name);
+ return val == null ? def : val;
+ }
+
+ /**
+ * Returns the value of the property or def if the property
+ * does not exist.
+ * @param name the name of the property
+ * @param def the default value to return if the property does not exist.
+ * @return the value of the property or def
+ */
+ public boolean getProperty(String name, boolean def) {
+ String val = getProperty(name);
+ return val == null ? def : Boolean.valueOf(getProperty(name)).booleanValue();
+ }
+
+ /**
+ * Enables or disables a command by setting the <id>.enabled property
+ * to enabled
+ *
+ * @param id
+ * @param enable
+ */
+ public void enableCommand(String id, boolean enable) {
+ setProperty(id + ".enabled", Boolean.toString(enable));
+ }
+
+ /**
+ * Enables or disables a command by setting the <id>.enabled property
+ * to enabled
+ *
+ * @param id
+ * @param enable
+ */
+ public void enableCommand(String id, String enable) {
+ setProperty(id + ".enabled", enable);
+ }
+
+ /**
+ * Checks if this command is enabled. if the respective property does not
+ * exist, the value of def is returned.
+ *
+ * @param id
+ * @param def
+ * @return
+ */
+ public boolean isCommandEnabled(String id, boolean def) {
+ return getProperty(id + ".enabled", def);
+ }
+
+}