/* * Copyright (C) 2009 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.services.jcr.impl.core.value; import org.exoplatform.services.jcr.access.AccessControlEntry; import org.exoplatform.services.jcr.config.WorkspaceEntry; import org.exoplatform.services.jcr.core.ExtendedPropertyType; import org.exoplatform.services.jcr.datamodel.Identifier; import org.exoplatform.services.jcr.datamodel.ValueData; import org.exoplatform.services.jcr.impl.Constants; import org.exoplatform.services.jcr.impl.core.JCRName; import org.exoplatform.services.jcr.impl.core.JCRPath; import org.exoplatform.services.jcr.impl.core.LocationFactory; import org.exoplatform.services.jcr.impl.core.NodeImpl; import org.exoplatform.services.jcr.impl.dataflow.SpoolConfig; import org.exoplatform.services.jcr.impl.dataflow.TransientValueData; import org.exoplatform.services.jcr.impl.util.JCRDateFormat; import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder; import org.exoplatform.services.jcr.storage.WorkspaceDataContainer; import org.exoplatform.services.log.ExoLogger; import org.exoplatform.services.log.Log; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Calendar; import javax.jcr.Node; import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.Value; import javax.jcr.ValueFactory; import javax.jcr.ValueFormatException; /** * Created by The eXo Platform SAS.<br> * ValueFactory implementation * * @author Gennady Azarenkov * @version $Id$ */ public class ValueFactoryImpl implements ValueFactory { protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.ValueFactoryImpl"); private LocationFactory locationFactory; private final SpoolConfig spoolConfig; public ValueFactoryImpl(LocationFactory locationFactory, WorkspaceEntry workspaceConfig, FileCleanerHolder cleanerHolder) { this.locationFactory = locationFactory; this.spoolConfig = new SpoolConfig(cleanerHolder.getFileCleaner()); this.spoolConfig.maxBufferSize = workspaceConfig.getContainer().getParameterInteger(WorkspaceDataContainer.MAXBUFFERSIZE_PROP, WorkspaceDataContainer.DEF_MAXBUFFERSIZE); } public ValueFactoryImpl(LocationFactory locationFactory, FileCleanerHolder cleanerHolder) { this.locationFactory = locationFactory; this.spoolConfig = new SpoolConfig(cleanerHolder.getFileCleaner()); } /** * {@inheritDoc} */ public Value createValue(String value, int type) throws ValueFormatException { if (value == null) return null; try { switch (type) { case PropertyType.STRING : return createValue(new String(value)); case PropertyType.BINARY : try { return createValue(new ByteArrayInputStream(value.getBytes(Constants.DEFAULT_ENCODING))); } catch (UnsupportedEncodingException e) { throw new RuntimeException( "FATAL ERROR Charset " + Constants.DEFAULT_ENCODING + " is not supported!", e); } case PropertyType.BOOLEAN : return createValue(Boolean.parseBoolean(value)); case PropertyType.LONG : return createValue(Long.parseLong(value)); case PropertyType.DOUBLE : return createValue(Double.parseDouble(value)); case PropertyType.DATE : Calendar cal = JCRDateFormat.parse(value); return createValue(cal); case PropertyType.PATH : try { JCRPath path; if (value.startsWith("/")) path = locationFactory.parseAbsPath(value); else path = locationFactory.parseRelPath(value); return createValue(path); } catch (RepositoryException e) { throw new ValueFormatException("Path '" + value + "' is invalid"); } case PropertyType.NAME : try { JCRName name = locationFactory.parseJCRName(value); return createValue(name); } catch (RepositoryException e) { throw new ValueFormatException("Name '" + value + "' is invalid", e); } case PropertyType.REFERENCE : return createValue(new Identifier(value)); case ExtendedPropertyType.PERMISSION : AccessControlEntry accessEntry = AccessControlEntry.parse(value); return new PermissionValue(new TransientValueData(accessEntry)); default : throw new ValueFormatException("unknown type " + type); } } catch (IllegalArgumentException e) { // NumberFormatException throw new ValueFormatException("Cant create value from string '" + value + "' for type " + PropertyType.nameFromValue(type)); } } /** * {@inheritDoc} */ public Value createValue(String value) { if (value == null) return null; try { return new StringValue(value); } catch (IOException e) { LOG.warn("Cannot create Value from String " + value, e); return null; } } /** * {@inheritDoc} */ public Value createValue(long value) { try { return new LongValue(value); } catch (IOException e) { LOG.warn("Cannot create Value from long " + value, e); return null; } } /** * {@inheritDoc} */ public Value createValue(double value) { try { return new DoubleValue(value); } catch (IOException e) { LOG.warn("Cannot create Value from double " + value, e); return null; } } /** * {@inheritDoc} */ public Value createValue(boolean value) { try { return new BooleanValue(value); } catch (IOException e) { LOG.warn("Cannot create Value from boolean " + value, e); return null; } } /** * {@inheritDoc} */ public Value createValue(Calendar value) { if (value == null) return null; try { return new DateValue(value); } catch (IOException e) { LOG.warn("Cannot create Value from Calendar " + value, e); return null; } } /** * {@inheritDoc} */ public Value createValue(InputStream value) { if (value == null) { return null; } try { return new BinaryValue(value, spoolConfig); } catch (IOException e) { LOG.warn("Cannot create Value from InputStream " + value, e); return null; } } /** * {@inheritDoc} */ public Value createValue(Node value) throws RepositoryException { if (value == null) return null; if (!value.isNodeType("mix:referenceable")) throw new ValueFormatException("Node " + value.getPath() + " is not referenceable"); try { if (value instanceof NodeImpl) { Identifier identifier = new Identifier(((NodeImpl)value).getInternalIdentifier()); return new ReferenceValue(new TransientValueData(identifier)); } else { throw new RepositoryException("Its need a NodeImpl instance of Node"); } } catch (IOException e) { throw new RepositoryException("Cannot create REFERENE Value from Node", e); } } // ///////////////////////// /** * Create Value from JCRName. * * @param value * JCRName * @return Value * @throws RepositoryException * if error */ public Value createValue(JCRName value) throws RepositoryException { if (value == null) return null; try { return new NameValue(value.getInternalName(), locationFactory); } catch (IOException e) { throw new RepositoryException("Cannot create NAME Value from JCRName", e); } } /** * Create Value from JCRPath. * * @param value * JCRPath * @return Value * @throws RepositoryException * if error */ public Value createValue(JCRPath value) throws RepositoryException { if (value == null) return null; try { return new PathValue(value.getInternalPath(), locationFactory); } catch (IOException e) { throw new RepositoryException("Cannot create PATH Value from JCRPath", e); } } /** * Create Value from Id. * * @param value * Identifier * @return Value Reference */ public Value createValue(Identifier value) { if (value == null) return null; try { return new ReferenceValue(value); } catch (IOException e) { LOG.warn("Cannot create REFERENCE Value from Identifier " + value, e); return null; } } /** * Creates new Value object using ValueData * * @param data * ValueData * @param type * int * @return Value * @throws RepositoryException * if error */ public Value loadValue(ValueData data, int type) throws RepositoryException { try { switch (type) { case PropertyType.STRING : return new StringValue(data); case PropertyType.BINARY : return new BinaryValue(data, spoolConfig); case PropertyType.BOOLEAN : return new BooleanValue(data); case PropertyType.LONG : return new LongValue(data); case PropertyType.DOUBLE : return new DoubleValue(data); case PropertyType.DATE : return new DateValue(data); case PropertyType.PATH : return new PathValue(data, locationFactory); case PropertyType.NAME : return new NameValue(data, locationFactory); case PropertyType.REFERENCE : return new ReferenceValue(data, true); case PropertyType.UNDEFINED : return null; case ExtendedPropertyType.PERMISSION : return new PermissionValue(data); default : throw new ValueFormatException("unknown type " + type); } } catch (IOException e) { throw new RepositoryException(e); } } public SpoolConfig getSpoolConfig() { return spoolConfig; } }