/**
* Licensed 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.brixcms.jcr.wrapper;
import org.apache.wicket.util.io.Streams;
import org.apache.wicket.util.string.Strings;
import org.brixcms.jcr.api.JcrNode;
import org.brixcms.jcr.api.JcrSession;
import org.brixcms.plugin.site.SitePlugin;
import org.brixcms.plugin.site.resource.ResourceNodePlugin;
import javax.jcr.Binary;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
/**
* Base class for nodes with content (with JCR primary type nt:file).
*
* @author Matej Knopp
* @see #initialize(JcrNode, String)
*/
public class BrixFileNode extends BrixNode {
/**
* Returns if the node is a file node,
*
* @param node
* @return <code>true</code> if the node is a file node, <code>false</code> otherwise
*/
public static boolean isFileNode(JcrNode node) {
if (!node.getPrimaryNodeType().getName().equals("nt:file")) {
return false;
}
return node.hasNode("jcr:content");
}
/**
* Initializes the specified node to be a valid file node. The node's primary type must be nt:file.
*
* @param node
* @param mimeType
* @return
*/
public static BrixFileNode initialize(JcrNode node, String mimeType) {
if (node.isNodeType("nt:file") == false) {
throw new IllegalStateException("Argument 'node' must have JCR type nt:file.");
} else if (node instanceof BrixFileNode) {
return (BrixFileNode) node;
}
node.addNode("jcr:content", "nt:resource");
BrixFileNode wrapped = new BrixFileNode(node.getDelegate(), node.getSession());
wrapped.setMimeType(mimeType);
wrapped.getContent().setProperty("jcr:lastModified", Calendar.getInstance());
wrapped.getContent().setProperty("jcr:data", "");
return wrapped;
}
/**
* Sets the mime type property
*
* @param mimeType
*/
public void setMimeType(String mimeType) {
getContent().setProperty("jcr:mimeType", mimeType);
}
public static boolean isText(String mimeType) {
if (Strings.isEmpty(mimeType)) {
return false;
}
if (mimeType.equals("text") || mimeType.startsWith("text/")) {
return true;
}
if ("application/xml".equals(mimeType)) {
return true;
}
return false;
}
public static boolean isText(BrixFileNode node) {
if (node == null) {
throw new IllegalArgumentException("Argument 'node' cannot be null");
}
return isText(node.getMimeType());
}
/**
* Returns the mime type property. If the property is not specified, tries to determine mime type from node name
* extension.
*
* @return
*/
public String getMimeType() {
return getMimeType(true);
}
/**
* Wraps the given delegate node using provided {@link JcrSession}.
*
* @param delegate
* @param session
*/
public BrixFileNode(Node delegate, JcrSession session) {
super(delegate, session);
}
private JcrNode getContent() {
return (JcrNode) getPrimaryItem();
}
/**
* Returns the length of content in bytes
*
* @return
*/
public long getContentLength() {
return getContent().getProperty("jcr:data").getLength();
}
/**
* Returns the data of this node as string
*
* @return
*/
public String getDataAsString() {
return getContent().getProperty("jcr:data").getString();
}
/**
* Returns the encoding property
*
* @return
*/
public String getEncoding() {
return getContent().hasProperty("jcr:encoding") ? getContent().getProperty("jcr:encoding")
.getString() : null;
}
/**
* Returns the mime type for this node. If the property is not specified and <code>useExtension</code> is
* <code>true</code>, tries to determine mime type from extension.
*
* @param useExtension
* @return
*/
public String getMimeType(boolean useExtension) {
// FIXME Shouldn't have direct dependency on SitePlugin
String mime = getContent().getProperty("jcr:mimeType").getString();
if (useExtension && (Strings.isEmpty(mime) || mime.equals("application/octet-stream"))) {
ResourceNodePlugin plugin = (ResourceNodePlugin) SitePlugin.get(getBrix())
.getNodePluginForType(ResourceNodePlugin.TYPE);
return plugin.resolveMimeTypeFromFileName(getName());
}
return mime;
}
/**
* Sets the actual data of this node
*
* @param data
*/
public void setData(Binary data) {
getContent().setProperty("jcr:data", data);
}
/**
* Sets the actual data of this node. Provided as complementary setter for {@link #getDataAsString()}.
*
* @param data
*/
public void setDataAsString(String data) {
setData(data);
}
/**
* Sets the actual data of this node
*
* @param data
*/
public void setData(String data) {
if (data == null) {
data = "";
}
setEncoding("UTF-8");
getContent().setProperty("jcr:data", data);
}
/**
* Sets the encoding property
*
* @param encoding
*/
public void setEncoding(String encoding) {
getContent().setProperty("jcr:encoding", encoding);
}
/**
* Writes the node data to the specified output stream.
*
* @param stream
* @throws IOException
*/
public void writeData(OutputStream stream) throws IOException {
Streams.copy(getDataAsStream(), stream);
}
/**
* Returns the data of this node as stream
*
* @return
*/
public InputStream getDataAsStream() {
try {
return getContent().getProperty("jcr:data").getBinary().getStream();
}
catch (RepositoryException e) {
throw new RuntimeException(e);
}
}
}