org.apache.jackrabbit.vault.fs.PropertyValueArtifact Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.sling.feature.analyser Show documentation
Show all versions of org.apache.sling.feature.analyser Show documentation
A feature describes an OSGi system
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jackrabbit.vault.fs;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.LinkedList;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.vault.fs.api.AccessType;
import org.apache.jackrabbit.vault.fs.api.Artifact;
import org.apache.jackrabbit.vault.fs.api.ArtifactType;
import org.apache.jackrabbit.vault.fs.api.ExportArtifact;
import org.apache.jackrabbit.vault.fs.api.SerializationType;
import org.apache.jackrabbit.vault.fs.api.VaultInputSource;
import org.apache.jackrabbit.vault.fs.impl.AbstractArtifact;
import org.apache.jackrabbit.vault.util.JcrConstants;
/**
* Implements a artifact that is based on a property value.
*
*/
public class PropertyValueArtifact extends AbstractArtifact implements ExportArtifact {
/**
* The property of this artifact
*/
private final Property property;
/**
* the path to the property
*/
private final String path;
/**
* Temporary file if the value is detached
*/
private File tmpFile;
/**
* cached content length
*/
private Long contentLength;
private final long lastModified;
/**
* The value index for multi value properties.
*/
private final int valueIndex;
public PropertyValueArtifact(Artifact parent, String relPath, String ext, ArtifactType type,
Property prop, long lastModified)
throws RepositoryException {
this(parent, relPath, ext, type, prop, -1, lastModified);
}
public PropertyValueArtifact(Artifact parent, String relPath, String ext, ArtifactType type,
Property prop, int index, long lastModified)
throws RepositoryException {
super(parent, relPath, ext, type);
this.property = prop;
this.path = prop.getPath();
if (prop.getDefinition().isMultiple()) {
if (index < 0) {
index = 0;
}
} else {
if (index >=0) {
index = -1;
}
}
this.valueIndex = index;
this.lastModified = lastModified;
}
/**
* Creates a collection of {@link PropertyValueArtifact} from the given
* property. If the property is multivalued there will be an artifact
* created for each value with the value index appended to it's name.
*
* @param parent parent artifact
* @param relPath the base name for the artifact(s).
* @param ext the extension
* @param type the type for the artifact(s).
* @param prop the property for the artifact(s).
* @param lastModified the last modified date.
*
* @return a collection of Artifacts.
* @throws RepositoryException if an error occurs
*/
public static Collection create(Artifact parent,
String relPath, String ext, ArtifactType type, Property prop, long lastModified)
throws RepositoryException {
LinkedList list = new LinkedList();
if (prop.getDefinition().isMultiple()) {
Value[] values = prop.getValues();
for (int i=0; i= values.length) {
throw new RepositoryException("Illegal value index: " + valueIndex);
}
return values[valueIndex];
}
}
/**
* {@inheritDoc}
*/
public long getContentLength() {
if (contentLength == null) {
if (tmpFile == null) {
contentLength = -1L;
try {
if (valueIndex < 0) {
contentLength = property.getLength();
} else {
long[] lengths = property.getLengths();
if (valueIndex < lengths.length) {
contentLength = lengths[valueIndex];
}
}
} catch (RepositoryException e) {
// ignore
}
} else {
contentLength = tmpFile.length();
}
}
return contentLength;
}
/**
* Returns the underlying property
* @return the underlying property
*/
public Property getProperty() {
return property;
}
/**
* {@inheritDoc}
*/
public long getLastModified() {
return lastModified;
}
/**
* {@inheritDoc}
*/
public String getContentType() {
String ct = super.getContentType();
if (ct == null && tmpFile == null) {
try {
Node parent = property.getParent();
if (parent.hasProperty(JcrConstants.JCR_MIMETYPE)) {
ct = parent.getProperty(JcrConstants.JCR_MIMETYPE).getString();
}
} catch (RepositoryException e) {
// ignore
}
super.setContentType(ct);
}
return ct;
}
/**
* Internal defered input stream on this property value
*/
private class PVAInputStream extends InputStream {
private InputStream stream;
private boolean closed;
private void assertOpen() throws IOException {
if (stream == null) {
if (closed) {
throw new IOException("Stream already closed.");
}
try {
stream = getValue().getStream();
} catch (RepositoryException e) {
throw new IOException("Error while opening stream: " + e.toString());
}
}
}
public int read() throws IOException {
assertOpen();
return stream.read();
}
public int read(byte[] b) throws IOException {
assertOpen();
return stream.read(b);
}
public int read(byte[] b, int off, int len) throws IOException {
assertOpen();
return stream.read(b, off, len);
}
public long skip(long n) throws IOException {
assertOpen();
return stream.skip(n);
}
public int available() throws IOException {
assertOpen();
return stream.available();
}
public void close() throws IOException {
try {
if (stream != null) {
stream.close();
}
} finally {
closed = true;
stream = null;
}
}
public void mark(int readlimit) {
try {
assertOpen();
} catch (IOException e) {
throw new IllegalStateException(e);
}
stream.mark(readlimit);
}
public void reset() throws IOException {
assertOpen();
stream.reset();
}
public boolean markSupported() {
try {
assertOpen();
} catch (IOException e) {
throw new IllegalStateException(e);
}
return stream.markSupported();
}
}
}