/* | |
* 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. | |
*/ | |
// COPIED FROM JACKRABBIT 2.4.0 | |
package org.apache.commons.vfs2.provider.webdav.test; | |
import java.io.InputStream; | |
import java.util.Calendar; | |
import javax.jcr.Node; | |
import javax.jcr.RepositoryException; | |
import javax.jcr.Value; | |
/** | |
* Collection of static utility methods for use with the JCR 1.0 API and Apache Jackrabbit 1.5.2. | |
* | |
* Copied, adapted and pruned down from Jackrabbit 2.4.0. | |
* | |
* @since 2.1 | |
*/ | |
class JcrUtils | |
{ | |
private static final String NodeType_NT_RESOURCE = "nt:resource"; | |
private static final String Node_JCR_CONTENT = "jcr:content"; | |
private static final String NodeType_NT_FOLDER = "nt:folder"; | |
private static final String NodeType_NT_FILE = "nt:file"; | |
private static final String Property_JCR_MIMETYPE = "jcr:mimeType"; | |
private static final String Property_JCR_ENCODING = "jcr:encoding"; | |
private static final String Property_JCR_LAST_MODIFIED = "jcr:lastModified"; | |
private static final String Property_JCR_DATA = "jcr:data"; | |
/** | |
* Returns the named child of the given node, creating it as an nt:folder node if it does not already exist. The caller is expected to | |
* take care of saving or discarding any transient changes. | |
* <p> | |
* Note that the type of the returned node is <em>not</em> guaranteed to match nt:folder in case the node already existed. The caller | |
* can use an explicit {@link Node#isNodeType(String)} check if needed, or simply use a data-first approach and not worry about the node | |
* type until a constraint violation is encountered. | |
* | |
* @param parent | |
* parent node | |
* @param name | |
* name of the child node | |
* @return the child node | |
* @throws RepositoryException | |
* if the child node can not be accessed or created | |
*/ | |
public static Node getOrAddFolder(final Node parent, final String name) throws RepositoryException | |
{ | |
return getOrAddNode(parent, name, NodeType_NT_FOLDER); | |
} | |
/** | |
* Returns the named child of the given node, creating the child if it does not already exist. If the child node gets added, then it is | |
* created with the given node type. The caller is expected to take care of saving or discarding any transient changes. | |
* | |
* @see Node#getNode(String) | |
* @see Node#addNode(String, String) | |
* @see Node#isNodeType(String) | |
* @param parent | |
* parent node | |
* @param name | |
* name of the child node | |
* @param type | |
* type of the child node, ignored if the child already exists | |
* @return the child node | |
* @throws RepositoryException | |
* if the child node can not be accessed or created | |
*/ | |
public static Node getOrAddNode(final Node parent, final String name, final String type) throws RepositoryException | |
{ | |
if (parent.hasNode(name)) | |
{ | |
return parent.getNode(name); | |
} else | |
{ | |
return parent.addNode(name, type); | |
} | |
} | |
/** | |
* Creates or updates the named child of the given node. If the child does not already exist, then it is created using the nt:file node | |
* type. This file child node is returned from this method. | |
* <p> | |
* If the file node does not already contain a jcr:content child, then one is created using the nt:resource node type. The following | |
* properties are set on the jcr:content node: | |
* <dl> | |
* <dt>jcr:mimeType</dt> | |
* <dd>media type</dd> | |
* <dt>jcr:encoding (optional)</dt> | |
* <dd>charset parameter of the media type, if any</dd> | |
* <dt>jcr:lastModified</dt> | |
* <dd>current time</dd> | |
* <dt>jcr:data</dt> | |
* <dd>binary content</dd> | |
* </dl> | |
* <p> | |
* Note that the types of the returned node or the jcr:content child are <em>not</em> guaranteed to match nt:file and nt:resource in | |
* case the nodes already existed. The caller can use an explicit {@link Node#isNodeType(String)} check if needed, or simply use a | |
* data-first approach and not worry about the node type until a constraint violation is encountered. | |
* <p> | |
* The given binary content stream is closed by this method. | |
* | |
* @param parent | |
* parent node | |
* @param name | |
* name of the file | |
* @param mime | |
* media type of the file | |
* @param data | |
* binary content of the file | |
* @return the child node | |
* @throws RepositoryException | |
* if the child node can not be created or updated | |
*/ | |
public static Node putFile(final Node parent, final String name, final String mime, final InputStream data) throws RepositoryException | |
{ | |
return putFile(parent, name, mime, data, Calendar.getInstance()); | |
} | |
/** | |
* Creates or updates the named child of the given node. If the child does not already exist, then it is created using the nt:file node | |
* type. This file child node is returned from this method. | |
* <p> | |
* If the file node does not already contain a jcr:content child, then one is created using the nt:resource node type. The following | |
* properties are set on the jcr:content node: | |
* <dl> | |
* <dt>jcr:mimeType</dt> | |
* <dd>media type</dd> | |
* <dt>jcr:encoding (optional)</dt> | |
* <dd>charset parameter of the media type, if any</dd> | |
* <dt>jcr:lastModified</dt> | |
* <dd>date of last modification</dd> | |
* <dt>jcr:data</dt> | |
* <dd>binary content</dd> | |
* </dl> | |
* <p> | |
* Note that the types of the returned node or the jcr:content child are <em>not</em> guaranteed to match nt:file and nt:resource in | |
* case the nodes already existed. The caller can use an explicit {@link Node#isNodeType(String)} check if needed, or simply use a | |
* data-first approach and not worry about the node type until a constraint violation is encountered. | |
* <p> | |
* The given binary content stream is closed by this method. | |
* | |
* @param parent | |
* parent node | |
* @param name | |
* name of the file | |
* @param mime | |
* media type of the file | |
* @param data | |
* binary content of the file | |
* @param date | |
* date of last modification | |
* @return the child node | |
* @throws RepositoryException | |
* if the child node can not be created or updated | |
*/ | |
public static Node putFile(final Node parent, final String name, final String mime, final InputStream data, final Calendar date) | |
throws RepositoryException | |
{ | |
final Value binary = parent.getSession().getValueFactory().createValue(data); | |
try | |
{ | |
final Node file = getOrAddNode(parent, name, NodeType_NT_FILE); | |
final Node content = getOrAddNode(file, Node_JCR_CONTENT, NodeType_NT_RESOURCE); | |
content.setProperty(Property_JCR_MIMETYPE, mime); | |
final String[] parameters = mime.split(";"); | |
for (int i = 1; i < parameters.length; i++) | |
{ | |
final int equals = parameters[i].indexOf('='); | |
if (equals != -1) | |
{ | |
final String parameter = parameters[i].substring(0, equals); | |
if ("charset".equalsIgnoreCase(parameter.trim())) | |
{ | |
content.setProperty(Property_JCR_ENCODING, parameters[i].substring(equals + 1).trim()); | |
} | |
} | |
} | |
content.setProperty(Property_JCR_LAST_MODIFIED, date); | |
content.setProperty(Property_JCR_DATA, binary); | |
return file; | |
} finally | |
{ | |
// JCR 2.0 API: | |
// binary.dispose(); | |
} | |
} | |
/** | |
* Private constructor to prevent instantiation of this class. | |
*/ | |
private JcrUtils() | |
{ | |
} | |
} |