001: /*
002: * Copyright 2006 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho
007: * BI Platform. The Initial Developer is Pentaho Corporation.
008: *
009: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
011: * the license for the specific language governing your rights and limitations.
012: *
013: * @created Dec 22, 2006
014: * @author James Dixon
015: *
016: */
017:
018: package org.pentaho.core.output;
019:
020: import java.io.InputStream;
021: import java.util.Calendar;
022: import java.util.StringTokenizer;
023:
024: import javax.jcr.NodeIterator;
025: import javax.jcr.Repository;
026: import javax.jcr.Session;
027: import javax.jcr.Node;
028: import javax.jcr.Workspace;
029: import javax.jcr.query.Query;
030: import javax.jcr.query.QueryManager;
031: import javax.jcr.query.QueryResult;
032: import javax.jcr.version.Version;
033: import javax.jcr.version.VersionHistory;
034: import javax.jcr.version.VersionIterator;
035:
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038: import org.pentaho.core.repository.IContentItem;
039: import org.pentaho.core.services.BufferedContentItem;
040: import org.pentaho.core.services.IContentListener;
041: import org.pentaho.messages.util.LocaleHelper;
042: import org.pentaho.util.logging.Logger;
043: import org.pentaho.messages.Messages;
044:
045: public abstract class JcrCmsOutputHandler extends BaseOutputHandler {
046:
047: public abstract Repository getRepository();
048:
049: private static final Log logger = LogFactory
050: .getLog(JcrCmsOutputHandler.class);
051:
052: public abstract Session getJcrSession(Repository repository);
053:
054: public IContentItem getFileOutputContentItem() {
055:
056: String contentName = getContentRef();
057: try {
058: Repository repository = getRepository();
059:
060: if (repository == null) {
061: Logger
062: .error(
063: JcrCmsOutputHandler.class.getName(),
064: Messages
065: .getString("JcrCmsOutputHandler.ERROR_0001_GETTING_CMSREPO")); //$NON-NLS-1$
066: return null;
067: }
068:
069: Session jcrSession = getJcrSession(repository);
070:
071: if (jcrSession == null) {
072: Logger
073: .error(
074: JcrCmsOutputHandler.class.getName(),
075: Messages
076: .getString("JcrCmsOutputHandler.ERROR_0002_GETTING_SESSION")); //$NON-NLS-1$
077: return null;
078: }
079:
080: // Use the root node as a starting point
081: Node root = jcrSession.getRootNode();
082: if (root == null) {
083: Logger
084: .error(
085: JcrCmsOutputHandler.class.getName(),
086: Messages
087: .getString("JcrCmsOutputHandler.ERROR_0003_GETTING_ROOT")); //$NON-NLS-1$
088: return null;
089: }
090:
091: Node node = root;
092:
093: // parse the path
094: StringTokenizer tokenizer = new StringTokenizer(
095: contentName, "/"); //$NON-NLS-1$
096: int levels = tokenizer.countTokens();
097: for (int idx = 0; idx < levels - 1; idx++) {
098: String folder = tokenizer.nextToken();
099: if (!node.hasNode(folder)) {
100: // Create an unstructured node under which to import the XML
101: node = node.addNode(folder, "nt:folder"); //$NON-NLS-1$
102: } else {
103: node = node.getNodes(folder).nextNode();
104: }
105: }
106: // we should be at the right level now
107: String fileName = tokenizer.nextToken();
108: Node fileNode = null;
109: Node contentNode = null;
110: Version version = null;
111: if (node.hasNode(fileName)) {
112: fileNode = node.getNode(fileName);
113: contentNode = fileNode.getNode("jcr:content"); //$NON-NLS-1$
114: if (contentNode.isLocked()) {
115: logger
116: .warn(Messages
117: .getString(
118: "JcrCmsOutputHandler.ERROR_0004_NODE_LOCKED", contentName)); //$NON-NLS-1$
119: return null;
120: }
121: if (contentNode.isCheckedOut()) {
122: logger
123: .warn(Messages
124: .getString(
125: "JcrCmsOutputHandler.ERROR_0005_NODE_CHECKED_OUT", contentName)); //$NON-NLS-1$
126: return null;
127: }
128: contentNode.checkout();
129: VersionHistory history = contentNode
130: .getVersionHistory();
131: VersionIterator iterator = history.getAllVersions();
132: while (iterator.hasNext()) {
133: version = iterator.nextVersion();
134: logger
135: .trace(version.getPath()
136: + "," + version.getName() + "," + version.getIndex() + "," + version.getCreated().toString()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
137: }
138:
139: } else {
140: fileNode = node.addNode(fileName, "nt:file"); //$NON-NLS-1$
141: fileNode.addMixin("mix:versionable"); //$NON-NLS-1$
142: // create the mandatory child node - jcr:content
143: contentNode = fileNode.addNode(
144: "jcr:content", "nt:resource"); //$NON-NLS-1$ //$NON-NLS-2$
145: contentNode.addMixin("mix:versionable"); //$NON-NLS-1$
146: contentNode.addMixin("mix:filename"); //$NON-NLS-1$
147: contentNode.setProperty("jcr:mimeType", getMimeType()); //$NON-NLS-1$
148: contentNode.setProperty("jcr:name", fileName); //$NON-NLS-1$
149: contentNode
150: .setProperty(
151: "jcr:encoding", LocaleHelper.getSystemEncoding()); //$NON-NLS-1$
152: }
153:
154: CmsContentListener listener = new CmsContentListener(
155: contentNode, jcrSession);
156: BufferedContentItem contentItem = new BufferedContentItem(
157: listener);
158: listener.setContentItem(contentItem);
159: if (false) { // Disable faked search for now
160: search("test", jcrSession); //$NON-NLS-1$
161: }
162: return contentItem;
163: } catch (Throwable t) {
164: Logger
165: .error(
166: JcrCmsOutputHandler.class.getName(),
167: Messages
168: .getString("JcrCmsOutputHandler.ERROR_0006_GETTING_OUTPUTHANDLER") + contentName, t); //$NON-NLS-1$
169: }
170:
171: return null;
172: }
173:
174: private void search(String searchStr, Session session) {
175: try {
176: Workspace workspace = session.getWorkspace();
177: QueryManager queryManager = workspace.getQueryManager();
178: Query query = queryManager
179: .createQuery(
180: "//*[jcr:contains(., '" + searchStr + "')]", Query.XPATH); //$NON-NLS-1$ //$NON-NLS-2$
181: QueryResult result = query.execute();
182: NodeIterator it = result.getNodes();
183: while (it.hasNext()) {
184: Node n = it.nextNode();
185: logger.trace(n.getName());
186: if (n.getName().equals("jcr:content")) { //$NON-NLS-1$
187: if (n.getProperty("jcr:mimeType") != null) { //$NON-NLS-1$
188: logger
189: .trace("jcr:mimeType=" + n.getProperty("jcr:mimeType").getString()); //$NON-NLS-1$ //$NON-NLS-2$
190: }
191: }
192: }
193: } catch (Throwable t) {
194: t.printStackTrace();
195: }
196:
197: }
198:
199: private class CmsContentListener implements IContentListener {
200:
201: private Node node;
202:
203: private Session session;
204:
205: private BufferedContentItem contentItem;
206:
207: public CmsContentListener() {
208: }
209:
210: public CmsContentListener(Node node, Session session) {
211: this .node = node;
212: this .session = session;
213: }
214:
215: public void close() {
216: try {
217: InputStream inputStream = contentItem.getInputStream();
218: node.setProperty("jcr:data", inputStream); //$NON-NLS-1$
219: Calendar lastModified = Calendar.getInstance();
220: node.setProperty("jcr:lastModified", lastModified); //$NON-NLS-1$
221: session.save();
222: node.checkin();
223: session.save();
224: } catch (Throwable t) {
225: Logger
226: .error(
227: JcrCmsOutputHandler.class.getName(),
228: Messages
229: .getString("JcrCmsOutputHandler.ERROR_0007_SAVING_CONTENT"), t); //$NON-NLS-1$
230: }
231:
232: }
233:
234: public void setNode(Node node) {
235: this .node = node;
236: }
237:
238: public void setSession(Session session) {
239: this .session = session;
240: }
241:
242: public void setContentItem(BufferedContentItem contentItem) {
243: this .contentItem = contentItem;
244: }
245:
246: public void setMimeType(String mimeType) {
247:
248: }
249:
250: }
251:
252: }
|