/* * 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. * */ package org.pentaho.platform.repository.content; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.platform.api.engine.IContentOutputHandler; import org.pentaho.platform.api.engine.IMimeTypeListener; import org.pentaho.platform.api.engine.IOutputDef; import org.pentaho.platform.api.engine.IOutputHandler; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IRuntimeContext; 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.repository.messages.Messages; public class CoreContentRepositoryOutputHandler implements IOutputHandler { private boolean responseExpected; private static final byte[] lock = new byte[0]; public static final String DefaultMimeType = "application/octet-stream"; //$NON-NLS-1$ public static final String BackgroundFolder = "background"; //$NON-NLS-1$ public static final String DefaultExtension = ".bin"; //$NON-NLS-1$ public static final String FileObjectName = "file"; //$NON-NLS-1$ private boolean contentGenerated; private IContentItem outputContentItem; private int outputType = IOutputHandler.OUTPUT_TYPE_DEFAULT; private String location; private String contentGUID; // private String solution; private String mimeType; private String extension; private int writeMode = IContentItem.WRITEMODE_OVERWRITE; private IPentahoSession userSession; protected IRuntimeContext runtimeContext; public CoreContentRepositoryOutputHandler(final String location, final String contentGUID, final String solution, final IPentahoSession session) { this(location, contentGUID, solution, CoreContentRepositoryOutputHandler.DefaultMimeType, CoreContentRepositoryOutputHandler.DefaultExtension, session); } public CoreContentRepositoryOutputHandler(final String location, final String contentGUID, final String solution, final String mimeType, final String extension, final IPentahoSession session) { this.contentGUID = contentGUID; this.location = location; //this.solution = solution; this.mimeType = mimeType; this.extension = extension; userSession = session; } public void setSession(final IPentahoSession session) { this.userSession = session; } public IPentahoSession getSession() { return userSession; } public void setMimeType(final String value) { mimeType = value; } public void setExtension(final String value) { extension = value; } public String getMimeType() { return mimeType; } public String getExtension() { return extension; } public void setWriteMode(final int value) { writeMode = value; } public int getWriteMode() { return writeMode; } public Log getLogger() { return LogFactory.getLog(ContentRepositoryOutputHandler.class); } public boolean allowFeedback() { return false; } public boolean contentDone() { return contentGenerated; } public IContentItem getFeedbackContentItem() { return null; } public IContentItem getOutputContentItem(final String objectName, final String contentName, final String solution, final String instanceId, final String inMimeType) { return getOutputContentItem(objectName, contentName, contentGUID, null, solution, instanceId, inMimeType); } public IContentItem getOutputContentItem(final String objectName, final String contentName, final String title, final String url, final String solution, final String instanceId, final String inMimeType) { contentGenerated = true; if (IOutputHandler.FILE.equalsIgnoreCase(objectName)) { IContentOutputHandler output = null; // this code allows us to stay backwards compatible if ((contentName != null) && (contentName.indexOf(":") == -1)) { //$NON-NLS-1$ output = PentahoSystem.getOutputDestinationFromContentRef(objectName + ":" + contentName, userSession); //$NON-NLS-1$ } else { output = PentahoSystem.getOutputDestinationFromContentRef(contentName, userSession); if (output == null) { output = PentahoSystem.getOutputDestinationFromContentRef(objectName + ":" + contentName, userSession); //$NON-NLS-1$ } } if (output != null) { output.setInstanceId(instanceId); output.setMimeType(mimeType); output.setSolutionName(solution); return output.getFileOutputContentItem(); } } if (outputContentItem == null) { if (inMimeType != null) { this.setMimeType(inMimeType); } // We need to create one now because someone is asking for it. IContentRepository contentRepository = PentahoSystem.get(IContentRepository.class, userSession); if (contentRepository == null) { getLogger().error(Messages.getInstance().getErrorString("RuntimeContext.ERROR_0024_NO_CONTENT_REPOSITORY")); //$NON-NLS-1$ return null; } 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 (CoreContentRepositoryOutputHandler.lock) { // Find the location if it's already there. IContentLocation contentLocation = null; try { contentLocation = contentRepository.getContentLocationByPath(location); } catch (Exception ex) { // ignored } if (contentLocation == null) { contentLocation = contentRepository.newContentLocation(location, contentName, contentName, solution, true); } if (contentLocation == null) { getLogger().error(Messages.getInstance().getErrorString("RuntimeContext.ERROR_0025_INVALID_CONTENT_LOCATION")); //$NON-NLS-1$ return null; } // Get the content item from the location - if it's there. try { contentItem = contentLocation.getContentItemByName(contentGUID); } catch (Exception ex) { // Ignored } if (contentItem == null) { // Create a contentItem with the ID that came from the contentGUID. // This must be a GUID or conflicts in the repository will happen. contentItem = contentLocation.newContentItem(contentGUID, contentGUID, title, extension, mimeType, url, writeMode); } outputContentItem = contentItem; } } if (objectName.equals(IOutputHandler.RESPONSE) && contentName.equals(IOutputHandler.CONTENT)) { responseExpected = true; } return outputContentItem; } public IOutputDef getOutputDef(final String name) { // TODO Auto-generated method stub return null; } public Map getOutputDefs() { // TODO Auto-generated method stub return null; } public int getOutputPreference() { // TODO Auto-generated method stub return outputType; } public void setContentItem(final IContentItem content, final String objectName, final String contentName) { outputContentItem = content; if (objectName.equals(IOutputHandler.RESPONSE) && contentName.equals(IOutputHandler.CONTENT)) { responseExpected = true; } } public void setOutput(final String name, final Object value) { if (IOutputHandler.CONTENT.equalsIgnoreCase(name)) { if (value instanceof IContentItem) { outputContentItem = (IContentItem) value; contentGenerated = true; } responseExpected = true; } } public void setOutputPreference(final int value) { this.outputType = value; } public IMimeTypeListener getMimeTypeListener() { return null; } public void setMimeTypeListener(final IMimeTypeListener mimeTypeListener) { // ignored } public void setRuntimeContext(final IRuntimeContext runtimeContext) { this.runtimeContext = runtimeContext; } public boolean isResponseExpected() { return responseExpected; } }