/* ===============================================================================
*
* Part of the InfoGlue Content Management Platform (www.infoglue.org)
*
* ===============================================================================
*
* Copyright (C)
*
* 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. See the file LICENSE.html for more information.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc. / 59 Temple
* Place, Suite 330 / Boston, MA 02111-1307 / USA.
*
* ===============================================================================
*/
package org.infoglue.cms.applications.managementtool.actions;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.StatusLine;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pluto.om.common.Preference;
import org.apache.pluto.om.common.PreferenceSet;
import org.apache.pluto.om.entity.PortletApplicationEntityList;
import org.apache.pluto.om.portlet.PortletApplicationDefinition;
import org.apache.pluto.om.portlet.PortletDefinition;
import org.apache.pluto.om.portlet.PortletDefinitionList;
import org.apache.pluto.portalImpl.services.portletentityregistry.PortletEntityRegistry;
import org.infoglue.cms.applications.common.actions.InfoGlueAbstractAction;
import org.infoglue.cms.controllers.kernel.impl.simple.PortletAssetController;
import org.infoglue.cms.entities.content.DigitalAsset;
import org.infoglue.cms.entities.content.DigitalAssetVO;
import org.infoglue.cms.exception.SystemException;
import org.infoglue.cms.util.CmsPropertyHandler;
import org.infoglue.deliver.portal.deploy.Deploy;
import org.infoglue.deliver.portal.om.PortletApplicationEntityImpl;
import org.infoglue.deliver.portal.om.PortletApplicationEntityListImpl;
import org.infoglue.deliver.portal.om.PortletEntityImpl;
import org.infoglue.deliver.portal.om.PreferenceImpl;
import org.infoglue.deliver.portal.om.PreferenceSetImpl;
import webwork.action.ActionContext;
import webwork.multipart.MultiPartRequestWrapper;
/**
* Upload a portlet-war. The war-file is stored as a digital asset.
*
* @author jand
*
*/
public class UploadPortletAction extends InfoGlueAbstractAction
{
private static final Log log = LogFactory.getLog(UploadPortletAction.class);
private static final String PORTLET_DEPLOY_PREFIX = "portlet.deploy";
private DigitalAsset digitalAsset;
public String doExecute() //throws Exception
{
try
{
MultiPartRequestWrapper mpr = ActionContext.getMultiPartRequest();
if (mpr == null)
{
return "input";
}
log.debug("Handling upload...");
Enumeration names = mpr.getFileNames();
if (names.hasMoreElements())
{
String name = (String) names.nextElement();
log.debug("name:" + name);
File uploadedFile = mpr.getFile(name);
if (uploadedFile == null || uploadedFile.length() == 0)
{
log.error("No file found in multipart request");
return "input";
}
String contentType = mpr.getContentType(name);
String fileName = mpr.getFilesystemName(name);
String filePath = CmsPropertyHandler.getDigitalAssetPath();
log.debug("fileName:" + fileName);
// Pluto prepare portlet-war
String appName = fileName;
int dot = appName.lastIndexOf(".");
if (dot > 0)
{
appName = appName.substring(0, dot);
}
log.info("appName:" + appName);
// Create file where Deployer will write updated
// (pluto-prepared) .war
File file = new File(uploadedFile.getParentFile(), "tmp" + System.currentTimeMillis());
log.info("file:" + file.getAbsolutePath());
PortletApplicationDefinition pad = Deploy.prepareArchive(uploadedFile, file, appName);
// Extract portlet application information to be added to
// portlet entity registry
log.info("Adding portlet application to registry: " + appName);
PortletApplicationEntityImpl pae = new PortletApplicationEntityImpl();
pae.setId(appName);
PortletDefinitionList pdl = pad.getPortletDefinitionList();
for (Iterator it = pdl.iterator(); it.hasNext();)
{
PortletDefinition pd = (PortletDefinition) it.next();
log.debug("Adding portlet: " + pd.getName());
PortletEntityImpl pe = new PortletEntityImpl();
pe.setId(pd.getName());
// Copy preferences
ArrayList destPrefs = new ArrayList();
PreferenceSet prefSet = pd.getPreferenceSet();
for (Iterator prefs = prefSet.iterator(); prefs.hasNext();)
{
Preference src = (Preference) prefs.next();
ArrayList destValues = new ArrayList();
for (Iterator values = src.getValues(); values.hasNext();)
{
destValues.add(values.next());
}
destPrefs.add(new PreferenceImpl(src.getName(), destValues));
}
pe.setPreferenceSet(new PreferenceSetImpl(destPrefs));
pae.addPortletEntity(pe);
}
// Create Digital Asset
log.debug("Creating Digital Asset...");
DigitalAssetVO newAsset = new DigitalAssetVO();
newAsset.setAssetContentType(contentType);
newAsset.setAssetKey(fileName);
newAsset.setAssetFileName(fileName);
newAsset.setAssetFilePath(filePath);
newAsset.setAssetFileSize(new Integer(new Long(file.length()).intValue()));
// Check existance of portlet and remove old ones
List assets = PortletAssetController.getDigitalAssetByName(fileName);
if (assets != null && assets.size() > 0)
{
log.info("Removing old instance of " + fileName);
for (Iterator it = assets.iterator(); it.hasNext();)
{
DigitalAsset oldAsset = (DigitalAsset) it.next();
PortletAssetController.delete(oldAsset.getId());
}
}
log.info("Storing Digital Asset (portlet) " + fileName);
InputStream is = new FileInputStream(file);
digitalAsset = PortletAssetController.create(newAsset, is);
is.close();
log.debug("Digital Asset stored as id=" + digitalAsset.getId());
// Cleanup
uploadedFile.delete();
file.delete();
// Add the new application to portlet registry
// Update persisted portlet registry
// TODO check existance first?
PortletApplicationEntityList pael = PortletEntityRegistry.getPortletApplicationEntityList();
if (pael instanceof PortletApplicationEntityListImpl)
{
((PortletApplicationEntityListImpl) pael).add(pae);
log.debug("Portlet application successfully added to registry");
} else
{
log.error("Unknown implementation of PortletApplicationEntityList, "
+ "cannot add portlet application!");
return "error";
}
PortletEntityRegistry.store();
// Refresh deliver-engines
updateDeliverEngines(digitalAsset.getId());
}
else
{
throw new SystemException("No file was uploaded...");
}
}
catch (Throwable e)
{
log.error("ERROR", e);
return "error";
}
return "success";
}
/**
* Report to deliver engines that a portlet has been uploaded
*
* @param contentId
* contentId of portlet
*/
private void updateDeliverEngines(Integer digitalAssetId)
{
List allUrls = CmsPropertyHandler.getInternalDeliveryUrls();
allUrls.addAll(CmsPropertyHandler.getPublicDeliveryUrls());
Iterator urlIterator = allUrls.iterator();
while(urlIterator.hasNext())
{
String url = (String)urlIterator.next() + "/DeployPortlet.action";
try
{
HttpClient client = new HttpClient();
// establish a connection within 5 seconds
client.setConnectionTimeout(5000);
// set the default credentials
HttpMethod method = new GetMethod(url);
method.setQueryString("digitalAssetId=" + digitalAssetId);
method.setFollowRedirects(true);
// execute the method
client.executeMethod(method);
StatusLine status = method.getStatusLine();
if (status != null && status.getStatusCode() == 200) {
log.info("Successfully deployed portlet at " + url);
} else {
log.warn("Failed to deploy portlet at " + url + ": " + status);
}
//clean up the connection resources
method.releaseConnection();
}
catch(Exception e)
{
e.printStackTrace();
}
}
/*
Properties props = CmsPropertyHandler.getProperties();
for (Enumeration keys = props.keys(); keys.hasMoreElements();) {
String key = (String) keys.nextElement();
if (key.startsWith(PORTLET_DEPLOY_PREFIX)) {
String url = props.getProperty(key);
try {
HttpClient client = new HttpClient();
//establish a connection within 5 seconds
client.setConnectionTimeout(5000);
//set the default credentials
HttpMethod method = new GetMethod(url);
method.setQueryString("digitalAssetId=" + digitalAssetId);
method.setFollowRedirects(true);
//execute the method
client.executeMethod(method);
StatusLine status = method.getStatusLine();
if (status != null && status.getStatusCode() == 200) {
log.info("Successfully deployed portlet at " + url);
} else {
log.warn("Failed to deploy portlet at " + url + ": " + status);
}
//clean up the connection resources
method.releaseConnection();
} catch (Throwable e) {
log.error(e.getMessage(), e);
}
}
}
*/
}
/**
* @return
*/
public DigitalAsset getDigitalAsset() {
return digitalAsset;
}
}