/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License, version 2 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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 General Public License for more details.
*
*
* Copyright 2006-2008 Pentaho Corporation. All rights reserved.
*
* @created Dec 21, 2006
* @author James Dixon
*
*/
package org.pentaho.platform.repository.content;
import org.pentaho.platform.api.repository.IContentItem;
import org.pentaho.platform.api.repository.IContentLocation;
import org.pentaho.platform.api.repository.IContentRepository;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.engine.services.outputhandler.BaseOutputHandler;
import org.pentaho.platform.repository.messages.Messages;
import org.pentaho.platform.util.logging.Logger;
public class ContentRepositoryOutputHandler extends BaseOutputHandler {
private static final byte[] lock = new byte[0];
@Override
public IContentItem getFileOutputContentItem() {
String contentRef = getContentRef();
// get an output stream to hand to the caller
IContentRepository contentRepository = PentahoSystem.get(IContentRepository.class, getSession());
if (contentRepository == null) {
Logger.error(this.getClass().getName(), Messages.getInstance()
.getErrorString("RuntimeContext.ERROR_0024_NO_CONTENT_REPOSITORY")); //$NON-NLS-1$
return null;
}
String extension = ""; //$NON-NLS-1$
int idx1 = contentRef.lastIndexOf("."); //$NON-NLS-1$
if (idx1 != -1) {
extension = contentRef.substring(idx1);
} else {
idx1 = contentRef.length();
}
String extensionFolder = extension;
if (extensionFolder.startsWith(".")) { //$NON-NLS-1$
extensionFolder = extensionFolder.substring(1);
}
int idx2 = contentRef.lastIndexOf("/"); //$NON-NLS-1$
String outputFolder = ""; //$NON-NLS-1$
String itemName = contentRef;
if (idx2 != -1) {
outputFolder = contentRef.substring(0, idx2);
}
itemName = contentRef.substring(idx2 + 1, idx1);
String contentPath = outputFolder + "/" + itemName + "/" + extensionFolder; //$NON-NLS-1$ //$NON-NLS-2$
IContentItem contentItem = null;
//
// Synchronizing solves a nasty race condition when
// multiple simultaneous threads ask Hibernate if a
// specific Location/Item exists. In all cases, the
// answer will be no, so they all create the corresponding
// object and tell Hibernate to save it. The end-result is
// exceptions thrown from the database for key-constraint violations.
// Synchronizing down to the create of the item will make sure
// that all pending saves get persistent.
//
synchronized (ContentRepositoryOutputHandler.lock) {
// Find the location if it's already there.
IContentLocation contentLocation = null;
try {
contentLocation = contentRepository.getContentLocationByPath(contentPath);
} catch (Exception ex) {
Logger.debug(this.getClass().getName(), contentPath, ex);
}
if (contentLocation == null) {
// Logger.debug(this.getClass().getName(),"******** New Location: " + contentPath + " - Thread: " + Thread.currentThread().getName()); //$NON-NLS-1$ //$NON-NLS-2$
contentLocation = contentRepository.newContentLocation(contentPath, contentRef, contentRef, getSolutionName(),
true);
}
if (contentLocation == null) {
Logger.error(this.getClass().getName(), Messages.getInstance()
.getErrorString("RuntimeContext.ERROR_0025_INVALID_CONTENT_LOCATION")); //$NON-NLS-1$
return null;
}
// TODO support content expiration
// TODO make the write mode based on the output definition
// Get the content item from the location - if it's there.
try {
contentItem = contentLocation.getContentItemByName(getInstanceId());
} catch (Exception ex) {
Logger.debug(this.getClass().getName(), getInstanceId(), ex);
}
if (contentItem == null) { // DM - Need to keep versions so each report
// in a burst gets saved
contentItem = contentLocation.newContentItem(getInstanceId(), contentRef, extension, getMimeType(), null,
IContentItem.WRITEMODE_KEEPVERSIONS);
}
}
return contentItem;
}
}