Package org.apache.jackrabbit.value

Source Code of org.apache.jackrabbit.value.ValueHelper

/*
* 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.name.IllegalNameException;
import org.apache.jackrabbit.name.MalformedPathException;
import org.apache.jackrabbit.name.Path;
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.util.Base64;
import org.apache.jackrabbit.util.Text;
import org.apache.jackrabbit.util.TransientFileFactory;

import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.FilterInputStream;

/**
* The <code>ValueHelper</code> class provides several <code>Value</code>
* related utility methods.
*/
public class ValueHelper {

    /**
     * empty private constructor
     */
    private ValueHelper() {
    }

    /**
     * @param srcValue
     * @param targetType
     * @return
     * @throws ValueFormatException
     * @throws IllegalArgumentException
     */
    public static Value convert(String srcValue, int targetType)
            throws ValueFormatException, IllegalArgumentException {
        if (srcValue == null) {
            return null;
        } else {
            return convert(new StringValue(srcValue), targetType);
        }
    }

    /**
     * @param srcValues
     * @param targetType
     * @return
     * @throws ValueFormatException
     * @throws IllegalArgumentException
     */
    public static Value[] convert(String[] srcValues, int targetType)
            throws ValueFormatException, IllegalArgumentException {
        if (srcValues == null) {
            return null;
        }
        Value[] newValues = new Value[srcValues.length];
        for (int i = 0; i < srcValues.length; i++) {
            newValues[i] = convert(srcValues[i], targetType);
        }
        return newValues;
    }

    /**
     * @param srcValues
     * @param targetType
     * @return
     * @throws ValueFormatException
     * @throws IllegalArgumentException
     */
    public static Value[] convert(Value[] srcValues, int targetType)
            throws ValueFormatException, IllegalArgumentException {
        if (srcValues == null) {
            return null;
        }

        Value[] newValues = new Value[srcValues.length];
        int srcValueType = PropertyType.UNDEFINED;
        for (int i = 0; i < srcValues.length; i++) {
            if (srcValues[i] == null) {
                newValues[i] = null;
                continue;
            }
            // check type of values
            if (srcValueType == PropertyType.UNDEFINED) {
                srcValueType = srcValues[i].getType();
            } else if (srcValueType != srcValues[i].getType()) {
                // inhomogeneous types
                String msg = "inhomogeneous type of values";
                throw new ValueFormatException(msg);
            }

            newValues[i] = convert(srcValues[i], targetType);
        }
        return newValues;
    }

    /**
     * @param srcValue
     * @param targetType
     * @return
     * @throws ValueFormatException
     * @throws IllegalStateException
     * @throws IllegalArgumentException
     */
    public static Value convert(Value srcValue, int targetType)
            throws ValueFormatException, IllegalStateException,
            IllegalArgumentException {
        if (srcValue == null) {
            return null;
        }

        Value val;
        int srcType = srcValue.getType();

        if (srcType == targetType) {
            // no conversion needed, return original value
            return srcValue;
        }

        switch (targetType) {
            case PropertyType.STRING:
                // convert to STRING
                try {
                    val = new StringValue(srcValue.getString());
                } catch (RepositoryException re) {
                    throw new ValueFormatException("conversion failed: "
                            + PropertyType.nameFromValue(srcType) + " to "
                            + PropertyType.nameFromValue(targetType), re);
                }
                break;

            case PropertyType.BINARY:
                // convert to BINARY
                try {
                    val = new BinaryValue(srcValue.getStream());
                } catch (RepositoryException re) {
                    throw new ValueFormatException("conversion failed: "
                            + PropertyType.nameFromValue(srcType) + " to "
                            + PropertyType.nameFromValue(targetType), re);
                }
                break;

            case PropertyType.BOOLEAN:
                // convert to BOOLEAN
                try {
                    val = new BooleanValue(srcValue.getBoolean());
                } catch (RepositoryException re) {
                    throw new ValueFormatException("conversion failed: "
                            + PropertyType.nameFromValue(srcType) + " to "
                            + PropertyType.nameFromValue(targetType), re);
                }
                break;

            case PropertyType.DATE:
                // convert to DATE
                try {
                    val = new DateValue(srcValue.getDate());
                } catch (RepositoryException re) {
                    throw new ValueFormatException("conversion failed: "
                            + PropertyType.nameFromValue(srcType) + " to "
                            + PropertyType.nameFromValue(targetType), re);
                }
                break;

            case PropertyType.DOUBLE:
                // convert to DOUBLE
                try {
                    val = new DoubleValue(srcValue.getDouble());
                } catch (RepositoryException re) {
                    throw new ValueFormatException("conversion failed: "
                            + PropertyType.nameFromValue(srcType) + " to "
                            + PropertyType.nameFromValue(targetType), re);
                }
                break;

            case PropertyType.LONG:
                // convert to LONG
                try {
                    val = new LongValue(srcValue.getLong());
                } catch (RepositoryException re) {
                    throw new ValueFormatException("conversion failed: "
                            + PropertyType.nameFromValue(srcType) + " to "
                            + PropertyType.nameFromValue(targetType), re);
                }
                break;

            case PropertyType.PATH:
                // convert to PATH
                switch (srcType) {
                    case PropertyType.PATH:
                        // no conversion needed, return original value
                        // (redundant code, just here for the sake of clarity)
                        return srcValue;

                    case PropertyType.BINARY:
                    case PropertyType.STRING:
                    case PropertyType.NAME: // a name is always also a relative path
                        // try conversion via string
                        String path;
                        try {
                            // get string value
                            path = srcValue.getString();
                        } catch (RepositoryException re) {
                            // should never happen
                            throw new ValueFormatException("failed to convert source value to PATH value",
                                    re);
                        }
                        try {
                            // check path format
                            Path.checkFormat(path);
                        } catch (MalformedPathException mpe) {
                            throw new ValueFormatException("source value " + path
                                    + " does not represent a valid path", mpe);
                        }
                        val = PathValue.valueOf(path);
                        break;

                    case PropertyType.BOOLEAN:
                    case PropertyType.DATE:
                    case PropertyType.DOUBLE:
                    case PropertyType.LONG:
                    case PropertyType.REFERENCE:
                        throw new ValueFormatException("conversion failed: "
                                + PropertyType.nameFromValue(srcType) + " to "
                                + PropertyType.nameFromValue(targetType));

                    default:
                        throw new IllegalArgumentException("not a valid type constant: " + srcType);
                }
                break;

            case PropertyType.NAME:
                // convert to NAME
                switch (srcType) {
                    case PropertyType.NAME:
                        // no conversion needed, return original value
                        // (redundant code, just here for the sake of clarity)
                        return srcValue;

                    case PropertyType.BINARY:
                    case PropertyType.STRING:
                    case PropertyType.PATH: // path might be a name (relative path of length 1)
                        // try conversion via string
                        String name;
                        try {
                            // get string value
                            name = srcValue.getString();
                        } catch (RepositoryException re) {
                            // should never happen
                            throw new ValueFormatException("failed to convert source value to NAME value",
                                    re);
                        }
                        try {
                            // check name format
                            QName.checkFormat(name);
                        } catch (IllegalNameException ine) {
                            throw new ValueFormatException("source value "
                                    + name
                                    + " does not represent a valid name", ine);
                        }
                        val = NameValue.valueOf(name);
                        break;

                    case PropertyType.BOOLEAN:
                    case PropertyType.DATE:
                    case PropertyType.DOUBLE:
                    case PropertyType.LONG:
                    case PropertyType.REFERENCE:
                        throw new ValueFormatException("conversion failed: "
                                + PropertyType.nameFromValue(srcType) + " to "
                                + PropertyType.nameFromValue(targetType));

                    default:
                        throw new IllegalArgumentException("not a valid type constant: " + srcType);
                }
                break;

            case PropertyType.REFERENCE:
                // convert to REFERENCE
                switch (srcType) {
                    case PropertyType.REFERENCE:
                        // no conversion needed, return original value
                        // (redundant code, just here for the sake of clarity)
                        return srcValue;

                    case PropertyType.BINARY:
                    case PropertyType.STRING:
                        // try conversion via string
                        String uuid;
                        try {
                            // get string value
                            uuid = srcValue.getString();
                        } catch (RepositoryException re) {
                            // should never happen
                            throw new ValueFormatException("failed to convert source value to REFERENCE value",
                                    re);
                        }
                        val = ReferenceValue.valueOf(uuid);
                        break;

                    case PropertyType.BOOLEAN:
                    case PropertyType.DATE:
                    case PropertyType.DOUBLE:
                    case PropertyType.LONG:
                    case PropertyType.PATH:
                    case PropertyType.NAME:
                        throw new ValueFormatException("conversion failed: "
                                + PropertyType.nameFromValue(srcType) + " to "
                                + PropertyType.nameFromValue(targetType));

                    default:
                        throw new IllegalArgumentException("not a valid type constant: " + srcType);
                }
                break;

            default:
                throw new IllegalArgumentException("not a valid type constant: " + targetType);
        }

        return val;
    }

    /**
     * @param srcValue
     * @return
     * @throws IllegalStateException
     */
    public static Value copy(Value srcValue) throws IllegalStateException {
        if (srcValue == null) {
            return null;
        }

        Value newVal = null;
        try {
            switch (srcValue.getType()) {
                case PropertyType.BINARY:
                    newVal = new BinaryValue(srcValue.getStream());
                    break;

                case PropertyType.BOOLEAN:
                    newVal = new BooleanValue(srcValue.getBoolean());
                    break;

                case PropertyType.DATE:
                    newVal = new DateValue(srcValue.getDate());
                    break;

                case PropertyType.DOUBLE:
                    newVal = new DoubleValue(srcValue.getDouble());
                    break;

                case PropertyType.LONG:
                    newVal = new LongValue(srcValue.getLong());
                    break;

                case PropertyType.PATH:
                    newVal = PathValue.valueOf(srcValue.getString());
                    break;

                case PropertyType.NAME:
                    newVal = NameValue.valueOf(srcValue.getString());
                    break;

                case PropertyType.REFERENCE:
                    newVal = ReferenceValue.valueOf(srcValue.getString());
                    break;

                case PropertyType.STRING:
                    newVal = new StringValue(srcValue.getString());
                    break;
            }
        } catch (RepositoryException re) {
            // should never get here
        }
        return newVal;
    }

    /**
     * @param srcValues
     * @return
     * @throws IllegalStateException
     */
    public static Value[] copy(Value[] srcValues) throws IllegalStateException {
        if (srcValues == null) {
            return null;
        }

        Value[] newValues = new Value[srcValues.length];
        for (int i = 0; i < srcValues.length; i++) {
            newValues[i] = copy(srcValues[i]);
        }
        return newValues;
    }

    /**
     * Serializes the given value to a <code>String</code>. 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
     * <code>{@link Value#getString()}</code> will be used.
     *
     * @param value        the value to be serialized
     * @param encodeBlanks if <code>true</code> space characters will be encoded
     *                     as <code>"_x0020_"</code> 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 <code>Writer</code>. 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
     * <code>{@link Value#getString()}</code> will be used for serialization.
     *
     * @param value        the value to be serialized
     * @param encodeBlanks if <code>true</code> space characters will be encoded
     *                     as <code>"_x0020_"</code> 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 <code>Value</code> of the given type.
     *
     * @param value        string to be deserialized
     * @param type         type of value
     * @param decodeBlanks if <code>true</code> <code>"_x0020_"</code>
     *                     character sequences will be decoded to single space
     *                     characters each.
     * @return the deserialized <code>Value</code>
     * @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(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 new BinaryValue(baos.toByteArray());
        } else {
            if (decodeBlanks) {
                // decode encoded blanks in value
                value = Text.replace(value, "_x0020_", " ");
            }
            return convert(value, type);
        }
    }

    /**
     * Deserializes the string data read from the given reader to a
     * <code>Value</code> of the given type.
     *
     * @param reader       reader for the string data to be deserialized
     * @param type         type of value
     * @param decodeBlanks if <code>true</code> <code>"_x0020_"</code>
     *                     character sequences will be decoded to single space
     *                     characters each.
     * @return the deserialized <code>Value</code>
     * @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(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

            // decode to temp file
            TransientFileFactory fileFactory = TransientFileFactory.getInstance();
            final File tmpFile = fileFactory.createTransientFile("bin", null, null);
            FileOutputStream out = new FileOutputStream(tmpFile);
            try {
                Base64.decode(reader, out);
            } finally {
                out.close();
            }

            // create an InputStream that keeps a hard reference to the temp file
            // in order to prevent its automatic deletion once the associated
            // File object is reclaimed by the garbage collector;
            // pass InputStream wrapper to BinaryValue constructor
            return new BinaryValue(new FilterInputStream(new FileInputStream(tmpFile)) {

                File f = tmpFile;

                public void close() throws IOException {
                    in.close();
                    // temp file can now safely be removed
                    f.delete();
                    f = null;
                }
            });
/*
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Base64.decode(reader, baos);
            // no need to close ByteArrayOutputStream
            //baos.close();
            return new BinaryValue(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 convert(value, type);
        }
    }
}
TOP

Related Classes of org.apache.jackrabbit.value.ValueHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.