Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package org.apache.jackrabbit.spi2davex;
 
 import static org.apache.jackrabbit.webdav.DavConstants.HEADER_ETAG;
 import static org.apache.jackrabbit.webdav.DavConstants.HEADER_LAST_MODIFIED;
 
 
 
 import java.io.File;
 import java.util.Map;

ValueFactoryImpl...
 
A dummy value for calling the constructor of AbstractQValue
 
     private static final Object DUMMY_VALUE = new Serializable() {
         private static final long serialVersionUID = -5667366239976271493L;
     };

    
empty array
 
     private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
 
     static final int NO_INDEX = -1;
 
     private final ValueLoader loader;
     private final ValueFactory vf;
 
     public QValueFactoryImpl() {
         this(nullnull);
     }
 
     QValueFactoryImpl(NamePathResolver resolverValueLoader loader) {
         this. = loader;
          = new ValueFactoryQImpl(thisresolver);
     }

    
Create a BINARY QValue with the given length and the given uri used to retrieve the value.

Parameters:
length Length of the binary value.
uri Uri from which the the binary value can be accessed.
index The index of the value within the values array.
Returns:
a new BINARY QValue.
 
     QValue create(long lengthString uriint index) {
        if ( == null) {
            throw new IllegalStateException();
        }
        return new BinaryQValue(lengthuriindex);
    }

    

Parameters:
uri The Uri from which the type info can be retrieved.
Returns:
the type of the property with the given uri.
Throws:
java.io.IOException If an error occurs.
javax.jcr.RepositoryException If an error occurs.
    int retrieveType(String urithrows IOExceptionRepositoryException {
        return .loadType(uri);
    }
    //--------------------------------------------------------< Inner Class >---

    
BinaryQValue represents a binary Value which is backed by a resource or byte[]. Unlike BinaryValue it has no state, i.e. the getStream() method always returns a fresh InputStream instance.
    private class BinaryQValue extends AbstractQValue implements ValueLoader.Target {
        private static final long serialVersionUID = 2736654000266713469L;

        
max size for keeping tmp data in memory
        private static final int MAX_BUFFER_SIZE = 0x10000;

        
underlying file
        private transient File file;

        
flag indicating if this instance represents a temporary value whose dynamically allocated resources can be explicitly freed on discard().
        private transient boolean temp;

        
Buffer for small-sized data
        private byte[] buffer;
        private Map<StringStringheaders;

        
URI to retrieve the value from
        private final String uri;
        private final long length;
        private final int index;
        private boolean initialized = true;
        private BinaryQValue(long lengthString uriint index) {
            super(.);
            this. = length;
            this. = uri;
            this. = index;
             = false;
        }

        
Creates a new BinaryQValue instance from an InputStream. The contents of the stream is spooled to a temporary file or to a byte buffer if its size is smaller than MAX_BUFFER_SIZE.

The temp parameter governs whether dynamically allocated resources will be freed explicitly on discard(). Note that any dynamically allocated resources (temp file/buffer) will be freed implicitly once this instance has been gc'ed.

Parameters:
in stream to be represented as a BinaryQValue instance
temp flag indicating whether this instance represents a temporary value whose resources can be explicitly freed on discard().
Throws:
java.io.IOException if an error occurs while reading from the stream or writing to the temporary file
        private void init(InputStream inboolean tempthrows IOException {
            byte[] spoolBuffer = new byte[0x2000];
            int read;
            int len = 0;
            OutputStream out = null;
            File spoolFile = null;
            try {
                while ((read = in.read(spoolBuffer)) > 0) {
                    if (out != null) {
                        // spool to temp file
                        out.write(spoolBuffer, 0, read);
                        len += read;
                    } else if (len + read > .) {
                        // threshold for keeping data in memory exceeded;
                        // create temp file and spool buffer contents
                        TransientFileFactory fileFactory = TransientFileFactory.getInstance();
                        spoolFile = fileFactory.createTransientFile("bin"nullnull);
                        out = new FileOutputStream(spoolFile);
                        out.write(, 0, len);
                        out.write(spoolBuffer, 0, read);
                         = null;
                        len += read;
                    } else {
                        // reallocate new buffer and spool old buffer contents
                        if ( == null) {
                             = ;
                        }
                        byte[] newBuffer = new byte[len + read];
                        System.arraycopy(, 0, newBuffer, 0, len);
                        System.arraycopy(spoolBuffer, 0, newBufferlenread);
                         = newBuffer;
                        len += read;
                    }
                }
            } finally {
                in.close();
                if (out != null) {
                    out.close();
                }
            }
            if (spoolFile == null &&  == null) {
                // input stream was empty -> initialize an empty binary value
                this. = false;
                 = ;
            } else {
                // init vars
                 = spoolFile;
                this. = temp;
            }
             = true;
        }
        //---------------------------------------------------------< QValue >---

        
Returns the length of this BinaryQValue.

Returns:
The length, in bytes, of this BinaryQValue, or -1L if the length can't be determined.
See also:
org.apache.jackrabbit.spi.QValue.getLength()
        @Override
        public long getLength() {
            if ( != null) {
                // this instance is backed by a 'real' file
                if (.exists()) {
                    return .length();
                } else {
                    return -1;
                }
            } else if ( != null) {
                // this instance is backed by an in-memory buffer
                return .;
            } else {
                // value has not yet been read from the server.
                return ;
            }
        }

        
        public InputStream getStream() throws RepositoryException {
            // if the value has not yet been loaded -> retrieve it first in
            // order to make sure that either 'file' or 'buffer' is set.
            if ( == null &&  == null) {
                try {
                    loadBinary();
                } catch (IOException e) {
                    throw new RepositoryException(e);
                }
            }
            // always return a 'fresh' stream
            if ( != null) {
                // this instance is backed by a 'real' file
                try {
                    return new FileInputStream();
                } catch (FileNotFoundException fnfe) {
                    throw new RepositoryException("file backing binary value not found",
                        fnfe);
                }
            } else {
                return new ByteArrayInputStream();
            }
        }

        
        @Override
        public Name getName() throws RepositoryException {
            throw new UnsupportedOperationException();
        }

        
        @Override
        public Path getPath() throws RepositoryException {
            throw new UnsupportedOperationException();
        }

        
Frees temporarily allocated resources such as temporary file, buffer, etc. If this BinaryQValue is backed by a persistent resource calling this method will have no effect.

        @Override
        public void discard() {
            if (!) {
                // do nothing if this instance is not backed by temporarily
                // allocated resource/buffer
                return;
            }
            if ( != null) {
                // this instance is backed by a temp file
                .delete();
            } else if ( != null) {
                // this instance is backed by an in-memory buffer
                 = ;
            }
        }

        
Resets the state of this value. a subsequent call to init() can be used to load the binary again. If this BinaryQValue is backed by a persistent resource calling this method will have no effect.

        public void reset() {
            if (!) {
                // do nothing if this instance is not backed by temporarily
                // allocated resource/buffer
                return;
            }
            if ( != null) {
                // this instance is backed by a temp file
                .delete();
            }
             = null;
             = null;
             = false;
        }
        //-----------------------------------------------< java.lang.Object >---
        
Returns a string representation of this BinaryQValue instance. The string representation of a resource backed value is the path of the underlying resource. If this instance is backed by an in-memory buffer the generic object string representation of the byte array will be used instead.

Returns:
A string representation of this BinaryQValue instance.
        @Override
        public String toString() {
            if ( != null) {
                // this instance is backed by a 'real' file
                return .toString();
            } else if ( != null) {
                // this instance is backed by an in-memory buffer
                return .toString();
            } else {
                return super.toString();
            }
        }

        
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj instanceof BinaryQValue) {
                BinaryQValue other = (BinaryQValueobj;
                // Consider unequal urls as unequal values and both urls null as equal values
                if (this. == null) {
                    return other.uri == null;
                }
                if (!this..equals(other.uri)) {
                    return false;
                }
                // Consider both uninitialized as equal values
                if (!this.preInitialized() && !other.preInitialized()) {
                    return true;
                }
                try {
                    // Initialized the one which is not
                    if (!this.preInitialized()) {
                        this.preInitialize(new String[] {});
                    } else if (!other.preInitialized()) {
                        other.preInitialize(new String[] {});
                    }
                } catch (RepositoryException e) {
                    return false;
                } catch (IOException e) {
                    return false;
                }
                // If we have headers try to determine equality from them
                if ( != null && !.isEmpty()) {
                    // Values are (un)equal if we have equal Etags
                    if (containKey(this.other.headers)) {
                        return equalValue(this.other.headers);
                    }
                    // Values are unequal if we have different Last-modified values
                    if (containKey(this.other.headers)) {
                        if (!equalValue(this.other.headers)) {
                            return false;
                        }
                    }
                // Otherwise compare binaries
                } else {
                    return (( == null ? other.file == null : .equals(other.file))
                        && Arrays.equals(other.buffer));
                }
            }
            return false;
        }


        
Returns zero to satisfy the Object equals/hashCode contract. This class is mutable and not meant to be used as a hash key.

Returns:
always zero
See also:
java.lang.Object.hashCode()
        @Override
        public int hashCode() {
            return 0;
        }
        //----------------------------------------------------------------------
        private synchronized void loadBinary() throws RepositoryExceptionIOException {
            if ( == null) {
                throw new IllegalStateException();
            }
            .loadBinary(this);
        }

        
Load the header with the given names. If none of the named headers exist, load binary.
        private void preInitialize(String[] headerNamesthrows IOExceptionRepositoryException {
             = .loadHeaders(headerNames);
            if (.isEmpty()) {
                loadBinary();
            }
        }

        

Returns:
true if either initialized or headers have been loaded, false otherwise.
        private boolean preInitialized() {
            return  ||  != null;
        }

        

Returns:
true if both maps contain the same value for key, false otherwise. The key must not map to null in either map.
        private boolean equalValue(String keyMap<StringStringmap1Map<StringStringmap2) {
            return map1.get(key).equals(map2.get(key));
        }

        

Returns:
true if both maps contains the key, false otherwise.
        private boolean containKey(String keyMap<StringStringmap1Map<StringStringmap2) {
            return map1.containsKey(key) && map2.containsKey(key);
        }
        //-----------------------------< Serializable >-------------------------
        private void writeObject(ObjectOutputStream out)
                throws IOException {
            out.defaultWriteObject();
            // write hasFile marker
            out.writeBoolean( != null);
            // then write file if necessary
            if ( != null) {
                byte[] buffer = new byte[4096];
                int bytes;
                InputStream stream = new FileInputStream();
                while ((bytes = stream.read(buffer)) >= 0) {
                    // Write a segment of the input stream
                    if (bytes > 0) {
                        // just to ensure that no 0 is written
                        out.writeInt(bytes);
                        out.write(buffer, 0, bytes);
                    }
                }
                // Write the end of stream marker
                out.writeInt(0);
                // close stream
                stream.close();
            }
        }
        private void readObject(ObjectInputStream in)
                throws IOExceptionClassNotFoundException {
            in.defaultReadObject();
            boolean hasFile = in.readBoolean();
            if (hasFile) {
                 = File.createTempFile("binary-qvalue""bin");
                OutputStream out = new FileOutputStream();
                byte[] buffer = new byte[4096];
                for (int bytes = in.readInt(); bytes > 0; bytes = in.readInt()) {
                    if (buffer.length < bytes) {
                        buffer = new byte[bytes];
                    }
                    in.readFully(buffer, 0, bytes);
                    out.write(buffer, 0, bytes);
                }
                out.close();
            }
            // deserialized value is always temp
             = true;
        }
        //---------------------------------------------------------< Target >---
        public void setStream(InputStream inthrows IOException {
            if ( == ) {
                init(intrue);
            } else {
                // TODO: improve. jcr-server sends XML for multivalued properties
                try {
                    Document doc = DomUtil.parseDocument(in);
                    Element prop = DomUtil.getChildElement(doc..);
                    DavProperty<?> p = DefaultDavProperty.createFromXml(prop);
                    Value[] jcrVs = ValueUtil.valuesFromXml(p.getValue(), .);
                    init(jcrVs[].getStream(), true);
                } catch (RepositoryException e) {
                    throw new IOException(e.getMessage());
                } catch (SAXException e) {
                    throw new IOException(e.getMessage());
                } catch (ParserConfigurationException e) {
                    throw new IOException(e.getMessage());
                }
            }
        }
    }
New to GrepCode? Check out our FAQ X