/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.vertical.adminweb;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.mail.MessagingException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.transform.TransformerException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.enonic.esl.containers.ExtendedMap;
import com.enonic.esl.containers.MultiValueMap;
import com.enonic.esl.net.URL;
import com.enonic.esl.servlet.http.CookieUtil;
import com.enonic.esl.util.Base64Util;
import com.enonic.esl.xml.XMLTool;
import com.enonic.vertical.adminweb.handlers.ContentBaseHandlerServlet;
import com.enonic.vertical.engine.VerticalEngineException;
import com.enonic.cms.framework.util.UrlPathDecoder;
import com.enonic.cms.framework.util.UrlPathEncoder;
import com.enonic.cms.framework.xml.XMLDocument;
import com.enonic.cms.core.resource.ResourceBase;
import com.enonic.cms.core.resource.ResourceFile;
import com.enonic.cms.core.resource.ResourceFolder;
import com.enonic.cms.core.resource.ResourceKey;
import com.enonic.cms.core.resource.xml.ResourceXmlCreator;
import com.enonic.cms.core.security.user.User;
import com.enonic.cms.core.service.AdminService;
import com.enonic.cms.core.DeploymentPathResolver;
public class ResourceHandlerServlet
extends AdminHandlerBaseServlet
{
private final static Logger LOG = LoggerFactory.getLogger( ResourceHandlerServlet.class );
private Document filterResources( Document resourceDoc, String searchText )
{
if ( searchText == null || searchText.length() == 0 )
{
return resourceDoc;
}
Element root = resourceDoc.getDocumentElement();
Element[] children = XMLTool.selectElements( root, "//resource" );
for ( Element child : children )
{
String name = child.getAttribute( "name" );
if ( !name.toLowerCase().contains( searchText.toLowerCase() ) )
{
child.getParentNode().removeChild( child );
}
}
return resourceDoc;
}
public void handlerBrowse( HttpServletRequest request, HttpServletResponse response, HttpSession session,
AdminService admin, ExtendedMap formItems, ExtendedMap parameters, User user, Document verticalDoc )
throws VerticalAdminException, TransformerException, IOException
{
String path = formItems.getString( "path", "/" );
String deploymentPath = DeploymentPathResolver.getAdminDeploymentPath( request );
String resourcePickerPathBase64Encoded = Base64Util.encode( path.getBytes( "UTF-8" ) );
String resourcePickerPathBase64EncodedAndUrlEncoded = UrlPathEncoder.encode( resourcePickerPathBase64Encoded );
CookieUtil.setCookie( response, "resourcePickerPath", resourcePickerPathBase64EncodedAndUrlEncoded,
ContentBaseHandlerServlet.COOKIE_TIMEOUT, deploymentPath );
Document doc;
if ( request.getParameter( "searchtext" ) != null )
{
String searchText = formItems.getString( "searchtext", "" );
doc = admin.getResourceTreeXml( path, true, true, -1, true, true ).getAsDOMDocument();
doc = filterResources( doc, searchText );
parameters.put( "searchtext", searchText );
parameters.put( "search", "true" );
}
else
{
doc = admin.getResourceTreeXml( path, true, true, 1, true, true ).getAsDOMDocument();
}
addAccessLevelParameters( user, parameters );
parameters.put( "mimetype", formItems.get( "mimetype", "" ) );
parameters.put( "extension", formItems.get( "extension", "" ) );
parameters.put( "fieldname", formItems.get( "fieldname" ) );
parameters.put( "path", doc.getDocumentElement().getAttribute( "root" ) );
parameters.put( "sortby", formItems.get( "sortby", "@name" ) );
parameters.put( "sortby-direction", formItems.get( "sortby-direction", "ascending" ) );
parameters.put( "reload", formItems.get( "reload", false ) );
parameters.put( "move", formItems.get( "move", false ) );
transformXML( request, response, doc, "resource_browse.xsl", parameters );
}
public void handlerCustom( HttpServletRequest request, HttpServletResponse response, HttpSession session,
AdminService admin, ExtendedMap formItems, String operation, ExtendedMap parameters, User user, Document verticalDoc )
throws VerticalAdminException, VerticalEngineException, MessagingException, IOException
{
if ( "popup".equals( operation ) )
{
handlerPopup( request, response, session, admin, formItems, parameters, user, verticalDoc );
}
else if ( "inuseby".equals( operation ) )
{
handlerInUseBy( request, response, session, admin, formItems, parameters, user, verticalDoc );
}
else if ( "moveFile".equals( operation ) )
{
handlerMove( request, response, session, admin, formItems, parameters, user, verticalDoc, false );
}
else if ( "moveFolder".equals( operation ) )
{
handlerMove( request, response, session, admin, formItems, parameters, user, verticalDoc, true );
}
else
{
super.handlerCustom( request, response, session, admin, formItems, operation, parameters, user, verticalDoc );
}
}
private void handlerPopup( HttpServletRequest request, HttpServletResponse response, HttpSession session,
AdminService admin, ExtendedMap formItems, ExtendedMap parameters, User user, Document verticalDoc )
throws VerticalAdminException
{
parameters.put( "mimetype", formItems.get( "mimetype", "" ) );
parameters.put( "extension", formItems.get( "extension", "" ) );
parameters.put( "fieldname", formItems.get( "fieldname" ) );
parameters.put( "user-agent", request.getHeader( "user-agent" ) );
transformXML( request, response, verticalDoc, "resource_selector_frameset.xsl", parameters );
}
public void handlerMenu( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, ExtendedMap parameters, User user, Document verticalDoc )
throws VerticalAdminException, TransformerException, IOException
{
//get resource tree xml
ResourceFolder root = resourceService.getResourceRoot();
ResourceXmlCreator xmlCreator = new ResourceXmlCreator();
xmlCreator.setIncludeFullPath( true );
xmlCreator.setListFolders( true );
xmlCreator.setListResources( false );
XMLDocument resourcesDoc = xmlCreator.createResourceTreeXml( root );
Cookie cookie = CookieUtil.getCookie( request, "resourcePickerPath" );
if ( cookie != null )
{
try
{
String resourcePickerPathBase64AndUrlEncoded = cookie.getValue();
String resourcePickerPathBase64Encoded = UrlPathDecoder.decode( resourcePickerPathBase64AndUrlEncoded );
String resourcePickerPath = new String( Base64Util.decode( resourcePickerPathBase64Encoded ), "UTF-8" );
if ( resourcePickerPath != null )
{
parameters.put( "path", resourcePickerPath );
}
}
catch ( IllegalArgumentException e )
{
LOG.warn( "Value in Cookie 'resourcePickerPath' is not base64 encoded " );
}
}
// add popup parameters
parameters.put( "mimetype", formItems.get( "mimetype", "" ) );
parameters.put( "extension", formItems.get( "extension", "" ) );
parameters.put( "fieldname", formItems.get( "fieldname" ) );
parameters.put( "subop", formItems.get( "subop", "" ) );
parameters.put( "sourceKey", formItems.get( "sourceKey", "" ) );
parameters.put( "destinationKey", formItems.get( "destinationKey", "" ) );
transformXML( request, response, resourcesDoc.getAsDOMDocument(), "resource_selector_frame1.xsl", parameters );
}
public void handlerInUseBy( HttpServletRequest request, HttpServletResponse response, HttpSession session,
AdminService admin, ExtendedMap formItems, ExtendedMap parameters, User user, Document verticalDoc )
throws VerticalAdminException
{
ResourceKey resourceKey = ResourceKey.from( formItems.getString( "resourcekey" ) );
ResourceXmlCreator xmlCreator = new ResourceXmlCreator();
ResourceFile resourceFile = resourceService.getResourceFile( resourceKey );
Document doc = null;
if ( resourceFile != null )
{
xmlCreator.setUsedByMap( resourceService.getUsedBy( resourceFile.getResourceKey() ) );
doc = xmlCreator.createResourceXml( resourceFile ).getAsDOMDocument();
}
transformXML( request, response, doc, "resource_inuseby.xsl", parameters );
}
public void handlerMove( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, ExtendedMap parameters, User user, Document verticalDoc, boolean moveFolder )
{
ResourceKey sourceKey = ResourceKey.from( formItems.getString( "sourceKey" ) );
ResourceBase source = resourceService.getResource( sourceKey );
if ( source == null )
{
throw new IllegalArgumentException( "Source (" + sourceKey + ") not found" );
}
ResourceKey destinationKey = ResourceKey.from( formItems.getString( "destinationKey" ) );
ResourceFolder destination = resourceService.getResourceFolder( destinationKey );
if ( destination == null )
{
throw new IllegalArgumentException( "Destination (" + destinationKey + ") not found" );
}
ResourceKey newSourceKey = resourceService.moveResource( source, destination );
if ( moveFolder )
{
URL url = new URL( request.getHeader( "referer" ) );
MultiValueMap params = new MultiValueMap();
params.putAll( url.getParameterMap() );
if ( params.containsKey( "reload" ) )
{
params.remove( "reload" );
}
params.put( "reload", "true" );
if ( params.containsKey( "path" ) )
{
params.remove( "path" );
}
params.put( "path", resolvePathForNewFolder( sourceKey, newSourceKey ) );
redirectClientToAdminPath( "adminpage", params, request, response );
}
else
{
redirectClientToReferer( request, response );
}
}
/*
* Extract the moving folder name from source path and compute the full destination path.
* Example:
* source: "/libraries/resolvers"
* destination: "/sites/stuff"
* we move folder "resolvers"
* result: "/sites/stuff/resolvers"
* @param sourceFolderPath source folder path (like "/libraries/resolvers")
* @param destinationFolderPath path to destination folder (like "/sites/stuff")
*/
protected String resolvePathForNewFolder( ResourceKey sourceFolderPath, ResourceKey destinationFolderPath )
{
Pattern pattern = Pattern.compile(".*/([^/]+)$");
Matcher matcher = pattern.matcher( sourceFolderPath.toString() );
String currentDir = "";
// extract the moving folder name
if ( matcher.matches() )
{
currentDir = matcher.group(1);
}
if ( StringUtils.isEmpty( currentDir ) )
{
return destinationFolderPath.toString();
}
// moving into root folder: / + moving folder
if ( "/".equals( destinationFolderPath.toString() ) )
{
return "/" + currentDir;
}
// computing destination path: destination + / + moving folder
return destinationFolderPath.toString() + "/" + currentDir;
}
}