/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.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 Lesser General Public License for more details.
*
* Copyright 2006 - 2009 Pentaho Corporation. All rights reserved.
*
*
* @created October 24, 2006
* @author Michael D'Amour
*
*/
package org.pentaho.platform.web.servlet;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Node;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.api.engine.ISolutionFile;
import org.pentaho.platform.api.engine.PentahoAccessControlException;
import org.pentaho.platform.api.repository.ISolutionRepository;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.util.client.PublisherUtil;
import org.pentaho.platform.util.messages.LocaleHelper;
import org.pentaho.platform.web.http.PentahoHttpSessionHelper;
public class RepositoryFilePublisher extends ServletBase {
private static final long serialVersionUID = 9019152264205996418L;
private static final Log logger = LogFactory.getLog(GetContent.class);
/**
* Provides utility methods for publishing solution files to the pentaho server.
*
*/
private static final String PublishConfigFile = "publisher_config.xml"; //$NON-NLS-1$
@Override
public Log getLogger() {
return RepositoryFilePublisher.logger;
}
public RepositoryFilePublisher() {
super();
}
@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
PentahoSystem.systemEntryPoint();
try {
response.setCharacterEncoding(LocaleHelper.getSystemEncoding());
IPentahoSession pentahoSession = PentahoHttpSessionHelper.getPentahoSession(request);
String publishPath = request.getParameter("publishPath"); //$NON-NLS-1$
String publishKey = request.getParameter("publishKey");//$NON-NLS-1$
String jndiName = request.getParameter("jndiName");//$NON-NLS-1$
String jdbcDriver = request.getParameter("jdbcDriver");//$NON-NLS-1$
String jdbcUrl = request.getParameter("jdbcUrl");//$NON-NLS-1$
String jdbcUserId = request.getParameter("jdbcUserId");//$NON-NLS-1$
String jdbcPassword = request.getParameter("jdbcPassword");//$NON-NLS-1$
boolean overwrite = Boolean.valueOf(request.getParameter("overwrite")).booleanValue(); //$NON-NLS-1$
boolean mkdirs = Boolean.valueOf(request.getParameter("mkdirs")).booleanValue(); //$NON-NLS-1$
List<FileItem> fileItems = Collections.emptyList();
try {
fileItems = getFileItems(request);
} catch (FileUploadException e) {
if (RepositoryFilePublisher.logger.isErrorEnabled()) {
RepositoryFilePublisher.logger.error("an exception occurred", e);
}
response.getWriter().println(ISolutionRepository.FILE_ADD_FAILED);
return;
}
int status = doPublish(fileItems, publishPath, publishKey, jndiName, jdbcDriver, jdbcUrl, jdbcUserId, jdbcPassword,
overwrite, mkdirs, pentahoSession);
response.getWriter().println(status);
} finally {
PentahoSystem.systemExitPoint();
}
}
protected List<FileItem> getFileItems(final HttpServletRequest request) throws FileUploadException {
ServletFileUpload fu = new ServletFileUpload(new DiskFileItemFactory());
// If file size exceeds, a FileUploadException will be thrown
fu.setSizeMax(10000000);
return fu.parseRequest(request);
}
protected int doPublish(final List<FileItem> fileItems, final String publishPath, final String publishKey,
final String jndiName, final String jdbcDriver, final String jdbcUrl, final String jdbcUserId,
final String jdbcPassword, final boolean overwrite, final boolean mkdirs, final IPentahoSession pentahoSession) {
ISolutionRepository repository = PentahoSystem.get(ISolutionRepository.class, pentahoSession);
int status = ISolutionRepository.FILE_ADD_SUCCESSFUL;
String cleanPublishPath = publishPath;
// Fix the publish path to prevent problems with the RDBMS repository.
if ((publishPath != null) && (publishPath.endsWith("/") || publishPath.endsWith("\\"))) { //$NON-NLS-1$ //$NON-NLS-2$
cleanPublishPath = publishPath.substring(0, publishPath.length() - 1);
}
cleanPublishPath = cleanPublishPath.replace( '\\' , ISolutionRepository.SEPARATOR );
if (RepositoryFilePublisher.checkPublisherKey(publishKey)) {
String solutionPath = PentahoSystem.getApplicationContext().getSolutionPath(""); //$NON-NLS-1$
try {
PentahoSystem.systemEntryPoint();
Iterator<FileItem> itr = fileItems.iterator();
ISolutionFile folder = repository.getSolutionFile(cleanPublishPath, ISolutionRepository.ACTION_CREATE);
if( folder == null ) {
if( mkdirs ) {
// we need to create the folder first
System.out.println("creating folders");
// check to see if the publish path exists
StringTokenizer tokenizer = new StringTokenizer( cleanPublishPath, ""+ISolutionRepository.SEPARATOR ); //$NON-NLS-1$
StringBuilder testPath = new StringBuilder();
int idx = 1;
while( tokenizer.hasMoreTokens() ) {
String folderName = tokenizer.nextToken();
testPath.append( ISolutionRepository.SEPARATOR ).append( folderName );
ISolutionFile testFolder = repository.getSolutionFile(testPath.toString(), ISolutionRepository.ACTION_CREATE);
if( idx == 1 && testFolder == null ) {
// we do not allow creation of top-level folders
status = ISolutionRepository.FILE_ADD_FAILED;
break;
}
else if( testFolder == null ) {
// create this one
String newFolderPath = PentahoSystem.getApplicationContext().getSolutionPath(testPath.toString());
File newFolder = new File(newFolderPath);
repository.createFolder(newFolder);
}
idx++;
}
} else {
// the folder does not exist
status = ISolutionRepository.FILE_ADD_FAILED;
}
}
if(status == ISolutionRepository.FILE_ADD_SUCCESSFUL) {
while (itr.hasNext() && (status == ISolutionRepository.FILE_ADD_SUCCESSFUL)) {
FileItem fi = itr.next();
status = repository.publish(solutionPath, cleanPublishPath, fi.getName(), fi.get(), overwrite);
}
}
} catch (PentahoAccessControlException e) {
status = ISolutionRepository.FILE_ADD_FAILED;
if (RepositoryFilePublisher.logger.isErrorEnabled()) {
RepositoryFilePublisher.logger.error("an error occurred", e);
}
} catch (IOException e) {
status = ISolutionRepository.FILE_ADD_FAILED;
if (RepositoryFilePublisher.logger.isErrorEnabled()) {
RepositoryFilePublisher.logger.error("an error occurred", e);
}
} finally {
PentahoSystem.systemExitPoint();
}
} else {
status = ISolutionRepository.FILE_ADD_INVALID_PUBLISH_PASSWORD;
}
return status;
}
/**
* Checks the publisher key in the publish_config.xml against the presented key.
*
* @param key
* The key to verify
* @return true if the presented key is the same as the one in publish_config.xml
*/
public static final boolean checkPublisherKey(final String key) {
if (key != null) {
Document doc = PentahoSystem.getSystemSettings().getSystemSettingsDocument(RepositoryFilePublisher.PublishConfigFile);
if (doc != null) {
Node node = doc.selectSingleNode("//publisher-config/publisher-password"); //$NON-NLS-1$
if (node != null) {
String setting = node.getText();
if ((setting != null) && (setting.length() > 0)) {
String pubKey = PublisherUtil.getPasswordKey(setting);
return pubKey.equals(key);
}
}
}
}
return false;
}
}