/* * 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.core.value; import org.apache.commons.io.IOUtils; import org.apache.jackrabbit.api.ReferenceBinary; import org.apache.jackrabbit.core.data.DataIdentifier; import org.apache.jackrabbit.core.data.DataRecord; import org.apache.jackrabbit.core.data.DataStore; import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl; import org.apache.jackrabbit.spi.QValue; import org.apache.jackrabbit.value.BinaryImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.jcr.Binary; import javax.jcr.Value; import javax.jcr.PropertyType; import javax.jcr.ValueFormatException; import javax.jcr.RepositoryException; import java.io.InputStream; import java.io.IOException; /** * <code>ValueFactoryImpl</code>... */ public class ValueFactoryImpl extends ValueFactoryQImpl { /** * logger instance */ private static final Logger log = LoggerFactory.getLogger(ValueFactoryImpl.class); private final DataStore store; /** * Constructs a new <code>ValueFactoryQImpl</code> based * on an existing SPI <code>QValueFactory</code> and a * <code>NamePathResolver</code>. * * @param resolver wrapped <code>NamePathResolver</code> */ public ValueFactoryImpl(NamePathResolver resolver, DataStore store) { super(new InternalValueFactory(store), resolver); this.store = store; } @Override public Value createValue(QValue qvalue) { if (qvalue instanceof InternalValue && PropertyType.BINARY == qvalue.getType()) { try { return new BinaryValueImpl(((InternalValue) qvalue).getBLOBFileValue().copy()); } catch (RepositoryException e) { // should not get here log.error(e.getMessage(), e); } } return super.createValue(qvalue); } @Override public Binary createBinary(InputStream stream) throws RepositoryException { try { QValue value = getQValueFactory().create(stream); if (value instanceof InternalValue) { return ((InternalValue) value).getBLOBFileValue(); } else { return new BinaryImpl(stream); } } catch (IOException e) { throw new RepositoryException(e); } finally { // JCR-2903 IOUtils.closeQuietly(stream); } } @Override public Value createValue(Binary binary) { try { if (binary instanceof BLOBInDataStore) { BLOBInDataStore blob = (BLOBInDataStore) binary; DataIdentifier identifier = blob.getDataIdentifier(); InternalValue value; if (blob.usesDataStore(store)) { value = InternalValue.getInternalValue(identifier, store, false); } else { value = InternalValue.getInternalValue(identifier, store, true); } if (value != null) { // if the value is already in this data store return new BinaryValueImpl(value.getBLOBFileValue()); } } else if (binary instanceof BLOBFileValue) { return new BinaryValueImpl(((BLOBFileValue) binary).copy()); } else if (binary instanceof ReferenceBinary) { String reference = ((ReferenceBinary) binary).getReference(); DataRecord record = store.getRecordFromReference(reference); if (record != null) { return new BinaryValueImpl(BLOBInDataStore.getInstance( store, record.getIdentifier())); } } return createValue(binary.getStream()); } catch (RepositoryException e) { log.error(e.getMessage(), e); // ignore - the super method may be smarter } return super.createValue(binary); } @Override public Value createValue(InputStream value) { try { InternalValue qvalue = (InternalValue) getQValueFactory().create(value); return new BinaryValueImpl(qvalue.getBLOBFileValue()); } catch (IOException ex) { throw new RuntimeException(ex); } catch (RepositoryException ex) { throw new RuntimeException(ex); } finally { // JCR-2903 IOUtils.closeQuietly(value); } } @Override public Value createValue(String value, int type) throws ValueFormatException { if (PropertyType.BINARY == type) { try { InternalValue qvalue = (InternalValue) getQValueFactory().create(value, type); return new BinaryValueImpl(qvalue.getBLOBFileValue()); } catch (RepositoryException e) { throw new ValueFormatException(e); } } else { return super.createValue(value, type); } } }