/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.vertical.adminweb;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import javax.annotation.PostConstruct;
import javax.mail.MessagingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
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.io.FileUtil;
import com.enonic.esl.net.URL;
import com.enonic.esl.net.URLUtil;
import com.enonic.esl.util.ParamsInTextParser;
import com.enonic.esl.util.StringUtil;
import com.enonic.esl.xml.XMLTool;
import com.enonic.vertical.VerticalException;
import com.enonic.vertical.VerticalRuntimeException;
import com.enonic.vertical.engine.VerticalEngineException;
import com.enonic.cms.framework.util.TIntArrayList;
import com.enonic.cms.core.content.binary.BinaryData;
import com.enonic.cms.core.content.category.CategoryAccessControl;
import com.enonic.cms.core.content.category.UnitEntity;
import com.enonic.cms.core.content.category.UnitKey;
import com.enonic.cms.core.content.contenttype.ContentTypeEntity;
import com.enonic.cms.core.resource.ResourceFile;
import com.enonic.cms.core.resource.ResourceKey;
import com.enonic.cms.core.security.group.GroupKey;
import com.enonic.cms.core.security.user.User;
import com.enonic.cms.core.security.user.UserEntity;
import com.enonic.cms.core.security.user.UserKey;
import com.enonic.cms.core.security.userstore.UserStoreKey;
import com.enonic.cms.core.service.AdminService;
import com.enonic.cms.core.structure.SiteEntity;
import com.enonic.cms.core.structure.page.template.PageTemplateEntity;
import com.enonic.cms.core.structure.page.template.PageTemplateSpecification;
import com.enonic.cms.core.structure.page.template.PageTemplateType;
import com.enonic.cms.core.xslt.XsltProcessorException;
import com.enonic.cms.core.xslt.admin.AdminXsltProcessorHelper;
public abstract class AdminHandlerBaseServlet
extends AbstractAdminwebServlet
{
protected static final int[] EXCLUDED_TYPE_KEYS_IN_PREVIEW = new int[]{1, 2, 3, 4, 6};
private Vector<ErrorCode> errorCodes = new Vector<ErrorCode>();
private FileUpload fileUpload;
private String defaultDataSourceRootElementName;
private long multiPartRequestMaxSize;
private String storeXHTML;
protected boolean isStoreXHTMLOn()
{
String ts = StringUtils.trimToNull( storeXHTML );
return !"false".equalsIgnoreCase( ts );
}
@PostConstruct
public void initialize()
{
final DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
diskFileItemFactory.setSizeThreshold( 64000 );
fileUpload = new FileUpload( diskFileItemFactory );
fileUpload.setHeaderEncoding( "UTF-8" );
fileUpload.setSizeMax( multiPartRequestMaxSize );
}
public void addError( int errorCode, String fieldName, String fieldValue )
{
// Check whether the error is already reported
for ( ErrorCode ec : errorCodes )
{
if ( ec.code == errorCode && ec.name.equals( fieldName ) )
{
return;
}
}
ErrorCode errCode = new ErrorCode( errorCode, fieldName, fieldValue );
errorCodes.add( errCode );
}
public void addFeedback( Document doc, int feedbackCode )
{
Element feedbackElem = XMLTool.createElementIfNotPresent( doc, doc.getDocumentElement(), "feedback" );
feedbackElem.setAttribute( "code", String.valueOf( feedbackCode ) );
}
public void addFeedback( Document doc, ExtendedMap formItems )
{
if ( formItems.containsKey( "feedback" ) )
{
addFeedback( doc, formItems.getInt( "feedback" ) );
}
}
public URL getReferer( HttpServletRequest request )
{
String refererStr = request.getHeader( "referer" );
if ( refererStr == null )
{
return null;
}
URL referer = new URL( refererStr );
// Remove feedback parameter
referer.removeParameter( "feedback" );
return referer;
}
public void addErrorsXML( Document doc )
{
if ( errorCodes.size() > 0 )
{
Element errorsElem = XMLTool.createElement( doc, doc.getDocumentElement(), "errors" );
for ( int i = 0; i < errorCodes.size(); i++ )
{
ErrorCode ec = errorCodes.get( i );
Element errorElem = XMLTool.createElement( doc, errorsElem, "error" );
errorElem.setAttribute( "code", Integer.toString( ec.code ) );
errorElem.setAttribute( "name", ec.name );
Element valueElem = XMLTool.createElement( doc, errorElem, "value" );
XMLTool.createCDATASection( doc, valueElem, ec.value );
}
}
errorCodes.removeAllElements();
}
public boolean hasErrors()
{
return !errorCodes.isEmpty();
}
public void clearErrors()
{
errorCodes.removeAllElements();
}
protected void closeWindow( HttpServletResponse response )
throws VerticalAdminException
{
try
{
PrintWriter out = response.getWriter();
out.print( "<html><head><script language=\"javascript\">window.close();</script></head></html>" );
}
catch ( IOException ioe )
{
String message = "Failed to print html response: %t";
VerticalAdminLogger.errorAdmin( message, ioe );
}
}
public static BinaryData createBinaryData( final FileItem fileItem )
throws VerticalAdminException
{
return createBinaryData( fileItem, null );
}
public static BinaryData createBinaryData( final FileItem fileItem, final String label )
throws VerticalAdminException
{
BinaryData binaryData = new BinaryData();
InputStream fis = null;
try
{
binaryData.fileName = FileUtil.getFileName( fileItem );
fis = fileItem.getInputStream();
ByteArrayOutputStream bao = new ByteArrayOutputStream();
byte[] buf = new byte[1024 * 10];
int size;
while ( ( size = fis.read( buf ) ) > 0 )
{
bao.write( buf, 0, size );
}
binaryData.data = bao.toByteArray();
binaryData.label = label;
}
catch ( IOException e )
{
VerticalAdminLogger.errorAdmin( "I/O error: %t", e );
}
finally
{
try
{
if ( fis != null )
{
fis.close();
}
}
catch ( IOException ioe )
{
String message = "Failed to close file input stream: %t";
VerticalAdminLogger.warn( message, ioe );
}
}
return binaryData;
}
/**
* Process incoming HTTP GET requests
*
* @param request Object that encapsulates the request to the servlet
* @param response Object that encapsulates the response from the servlet
*/
public void doGet( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException
{
performTask( request, response );
}
/**
* Process incoming HTTP POST requests
*
* @param request Object that encapsulates the request to the servlet
* @param response Object that encapsulates the response from the servlet
*/
public void doPost( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException
{
performTask( request, response );
}
public void handlerBrowse( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, ExtendedMap parameters, User user, Document verticalDoc )
throws VerticalAdminException, TransformerException, IOException
{
handlerBrowse( request, response, session, admin, formItems );
}
public void handlerBrowse( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems )
throws VerticalAdminException
{
String message = "OperationWrapper BROWSE is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
public void handlerCopy( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, User user, int key )
throws VerticalAdminException, VerticalEngineException
{
String message = "OperationWrapper COPY is not implemented (page={0},key={1})";
Object[] msgData = new Object[]{formItems.getString( "page" ), key};
VerticalAdminLogger.errorAdmin( message, msgData );
}
public void handlerCreate( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems )
throws VerticalAdminException, VerticalEngineException, IOException, MessagingException
{
String message = "OperationWrapper CREATE is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
public void handlerReport( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, String subop )
throws VerticalAdminException, VerticalEngineException
{
String message = "OperationWrapper REPORT is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
public void handlerPreview( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems )
throws VerticalAdminException, VerticalEngineException
{
String message = "OperationWrapper PREVIEW is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
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
{
handlerCustom( request, response, session, admin, formItems, operation );
}
public void handlerCustom( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, String operation )
throws VerticalAdminException, VerticalEngineException, MessagingException, IOException
{
String message = "Custom operation is not implemented (page={0}): {1}";
Object[] msgData = new Object[]{formItems.get( "page" ), operation};
VerticalAdminLogger.errorAdmin( message, msgData );
}
public void handlerForm( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems )
throws VerticalAdminException, VerticalEngineException, IOException, MessagingException
{
String message = "OperationWrapper FORM is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
public void addCommonParameters( AdminService admin, User user, HttpServletRequest request, Map<String, Object> parameters, int unitKey,
int menuKey )
{
if ( user != null )
{
UserEntity userEntity = securityService.getUser( user );
parameters.put( "currentuser_key", userEntity.getKey().toString() );
parameters.put( "current_uid", userEntity.getName() );
parameters.put( "currentuser_uid", userEntity.getName() );
parameters.put( "currentuser_fullname", userEntity.getDisplayName() );
parameters.put( "currentuser_qualifiedname", userEntity.getQualifiedName() );
parameters.put( "currentuser_email", userEntity.getEmail() != null ? userEntity.getEmail() : "" );
parameters.put( "currentuser_has_photo", userEntity.hasPhoto() );
}
if ( unitKey != -1 )
{
UnitEntity unit = unitDao.findByKey( new UnitKey( unitKey ) );
parameters.put( "unitname", unit.getName() );
parameters.put( "selectedunitkey", String.valueOf( unitKey ) );
}
if ( menuKey != -1 )
{
SiteEntity site = siteDao.findByKey( menuKey );
if ( site != null )
{
parameters.put( "menuname", site.getName() );
parameters.put( "menukey", String.valueOf( menuKey ) );
}
}
if ( !parameters.containsKey( "referer" ) && request.getHeader( "referer" ) != null )
{
parameters.put( "referer", request.getHeader( "referer" ) );
}
}
public void handlerRemove( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, int key )
throws VerticalAdminException, VerticalEngineException
{
String message = "OperationWrapper REMOVE is not implemented (page={0},key={1})";
Object[] msgData = new Object[]{formItems.get( "page" ), key};
VerticalAdminLogger.errorAdmin( message, msgData );
}
public void handlerRemove( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, String key )
throws VerticalAdminException, VerticalEngineException
{
String message = "OperationWrapper REMOVE is not implemented (page={0},key={1})";
Object[] msgData = new Object[]{formItems.get( "page" ), key};
VerticalAdminLogger.errorAdmin( message, msgData );
}
public void handlerSearch( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems )
throws VerticalAdminException
{
String message = "OperationWrapper SEARCH is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
public void handlerSearchResults( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems )
throws VerticalAdminException
{
String message = "OperationWrapper SEARCH RESULTS is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
public void handlerMenu( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, ExtendedMap parameters, User user, Document verticalDoc )
throws VerticalAdminException, TransformerException, IOException
{
String message = "OperationWrapper MENU is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
public void handlerWizard( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, ExtendedMap parameters, User user, String wizardName )
throws VerticalAdminException, VerticalEngineException, TransformerException, IOException, MessagingException
{
String message = "OperationWrapper WIZARD is not implemented (page={0},wizardName={1})";
Object[] msgData = {formItems.get( "page" ), wizardName};
VerticalAdminLogger.errorAdmin( message, msgData );
}
public void handlerNotify( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems, User user )
throws VerticalAdminException, IOException, MessagingException
{
String message = "OperationWrapper NOTIFY is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
public boolean handlerSelect( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems )
throws VerticalAdminException
{
String message = "OperationWrapper SELECT is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
return false;
}
public void handlerShow( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems )
throws VerticalAdminException
{
String message = "OperationWrapper SHOW is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
public void handlerUpdate( HttpServletRequest request, HttpServletResponse response, HttpSession session, AdminService admin,
ExtendedMap formItems )
throws VerticalAdminException, VerticalEngineException, IOException, MessagingException
{
String message = "OperationWrapper UPDATE is not implemented (page={0})";
VerticalAdminLogger.errorAdmin( message, formItems.get( "page" ), null );
}
public static boolean isArrayFormItem( Map formItems, String string )
{
if ( !formItems.containsKey( string ) )
{
return false;
}
if ( formItems.get( string ) == null )
{
return false;
}
return formItems.get( string ).getClass() == String[].class;
}
public static String[] getArrayFormItem( Map formItems, String string )
{
if ( !formItems.containsKey( string ) )
{
return new String[0];
}
Object item = formItems.get( string );
if ( item == null )
{
return new String[0];
}
if ( item.getClass() == String[].class )
{
return (String[]) item;
}
else
{
return new String[]{(String) item};
}
}
private ExtendedMap parseSimpleRequest( HttpServletRequest request, boolean keepEmpty )
{
ExtendedMap formItems = new ExtendedMap( keepEmpty );
Enumeration paramNames = request.getParameterNames();
while ( paramNames.hasMoreElements() )
{
String key = paramNames.nextElement().toString();
String[] paramValues = request.getParameterValues( key );
if ( paramValues != null )
{
if ( paramValues.length == 1 && paramValues[0] != null )
{
String value = paramValues[0];
if ( value.length() > 0 )
{
if ( "true".equals( value ) )
{
formItems.putBoolean( key, true );
}
else if ( "false".equals( value ) )
{
formItems.putBoolean( key, false );
}
else
{
formItems.putString( key, value );
}
}
else if ( keepEmpty )
{
formItems.putString( key, value );
}
}
else if ( paramValues.length > 1 )
{
formItems.put( key, paramValues );
}
}
}
return formItems;
}
protected ExtendedMap parseForm( HttpServletRequest request )
throws FileUploadException, IOException
{
if ( FileUploadBase.isMultipartContent( new ServletRequestContext( request ) ) )
{
return parseMultiPartRequest( request );
}
else
{
return parseSimpleRequest( request, false );
}
}
private ExtendedMap parseMultiPartRequest( HttpServletRequest request )
throws FileUploadException, IOException
{
ExtendedMap formItems = new ExtendedMap();
List paramList = fileUpload.parseRequest( new ServletRequestContext( request ) );
for ( Object parameter : paramList )
{
FileItem fileItem = (FileItem) parameter;
String name = fileItem.getFieldName();
if ( fileItem.isFormField() )
{
String value = fileItem.getString( "UTF-8" );
if ( formItems.containsKey( name ) )
{
ArrayList<Object> values = new ArrayList<Object>();
Object obj = formItems.get( name );
if ( obj instanceof Object[] )
{
String[] objArray = (String[]) obj;
for ( int i = 0; i < objArray.length; i++ )
{
values.add( objArray[i] );
}
}
else
{
values.add( obj );
}
values.add( value );
formItems.put( name, values.toArray( new String[values.size()] ) );
}
else
{
formItems.put( name, value );
}
}
else
{
if ( fileItem.getSize() > 0 )
{
if ( formItems.containsKey( name ) )
{
ArrayList<Object> values = new ArrayList<Object>();
Object obj = formItems.get( name );
if ( obj instanceof FileItem[] )
{
FileItem[] objArray = (FileItem[]) obj;
for ( int i = 0; i < objArray.length; i++ )
{
values.add( objArray[i] );
}
}
else
{
values.add( obj );
}
values.add( fileItem );
formItems.put( name, values.toArray( new FileItem[values.size()] ) );
}
else
{
formItems.put( name, fileItem );
}
}
}
}
// Add parameters from url
Map paramMap = URLUtil.decodeParameterMap( request.getParameterMap() );
for ( Object parameterEntry : paramMap.entrySet() )
{
Map.Entry entry = (Map.Entry) parameterEntry;
String key = (String) entry.getKey();
String[] values = (String[]) entry.getValue();
for ( String value : values )
{
formItems.put( key, value );
}
}
// Remove all empty parameters that are NOT in an array
ArrayList<String> remove = new ArrayList<String>();
for ( Object parameterKey : formItems.keySet() )
{
String key = (String) parameterKey;
Object value = formItems.get( key );
if ( !( value instanceof String[] ) && value instanceof String && ( (String) value ).length() == 0 )
{
remove.add( key );
}
}
for ( String key : remove )
{
formItems.remove( key );
}
return formItems;
}
/**
* Process incoming requests for information
*
* @param request Object that encapsulates the request to the servlet
* @param response Object that encapsulates the response from the servlet
*/
protected void performTask( HttpServletRequest request, HttpServletResponse response )
{
HttpSession session;
session = request.getSession( false );
response.setContentType( "text/html;charset=UTF-8" );
if ( session == null )
{
VerticalAdminLogger.debug( "Session is null. Redirecting to login." );
// failed to get session, redirect to login page
try
{
redirectClientToAdminPath( "login", (MultiValueMap) null, request, response );
}
catch ( VerticalAdminException vae )
{
String message = "Failed to redirect to login page: %t";
VerticalAdminLogger.errorAdmin( message, vae );
}
}
else
{
// lookup admin bean
AdminService admin = lookupAdminBean();
User user = securityService.getLoggedInAdminConsoleUser();
if ( user == null )
{
// no logged in user, invalidate session and redirect to login page
String message = "No user logged in. Redirecting to login.";
VerticalAdminLogger.debug( message );
try
{
redirectClientToAdminPath( "login", (MultiValueMap) null, request, response );
}
catch ( VerticalAdminException vae )
{
message = "Failed to redirect to login page: %t";
VerticalAdminLogger.errorAdmin( message, vae );
}
}
else
{
response.setContentType( "text/html; charset=UTF-8" );
try
{
ExtendedMap formItems = parseForm( request );
String operation;
if ( formItems.containsKey( "op" ) )
{
operation = formItems.getString( "op" );
}
else
{
operation = request.getParameter( "op" );
}
// Common parameters and variables
ExtendedMap parameters = new ExtendedMap();
int unitKey = formItems.getInt( "selectedunitkey", -1 );
int menuKey = formItems.getInt( "selectedmenukey", -1 );
int page = formItems.getInt( "page", -1 );
if ( page == 993 )
{
int contentKey = -1;
String contentKeyStr = request.getParameter( "key" );
if ( contentKeyStr != null )
{
contentKey = Integer.parseInt( contentKeyStr );
}
if ( contentKey == -1 )
{
String versionKeyStr = request.getParameter( "versionkey" );
if ( versionKeyStr != null )
{
int versionKey = Integer.parseInt( versionKeyStr );
contentKey = admin.getContentKeyByVersionKey( versionKey );
}
}
if ( contentKey != -1 )
{
int contentTypeKey = admin.getContentTypeKey( contentKey );
page = contentTypeKey + 999;
formItems.put( "page", page );
}
}
if ( page == 991 )
{
int categoryKey = formItems.getInt( "categorykey", -1 );
if ( categoryKey == -1 )
{
categoryKey = formItems.getInt( "cat", -1 );
}
if ( categoryKey != -1 )
{
int contentTypeKey = admin.getContentTypeKeyByCategory( categoryKey );
if ( contentTypeKey != -1 )
{
page = contentTypeKey + 999;
}
}
}
parameters.put( "page", Integer.toString( page ) );
addCommonParameters( admin, user, request, parameters, unitKey, menuKey );
Document verticalDoc = XMLTool.createDocument( "data" );
if ( "create".equals( operation ) )
{
handlerCreate( request, response, session, admin, formItems );
}
else if ( "update".equals( operation ) )
{
handlerUpdate( request, response, session, admin, formItems );
}
else if ( "remove".equals( operation ) )
{
String keyStr = request.getParameter( "key" );
if ( StringUtil.isIntegerString( keyStr ) )
{
int key = -1;
try
{
key = Integer.parseInt( keyStr );
}
catch ( NumberFormatException nfe )
{
String message = "Failed to parse key ({0}): %t";
VerticalAdminLogger.errorAdmin( message, keyStr, nfe );
}
handlerRemove( request, response, session, admin, formItems, key );
}
else
{
handlerRemove( request, response, session, admin, formItems, keyStr );
}
}
else if ( "copy".equals( operation ) )
{
String keyStr = request.getParameter( "key" );
int key = -1;
try
{
key = Integer.parseInt( keyStr );
}
catch ( NumberFormatException nfe )
{
String message = "Failed to parse key ({0}): %t";
VerticalAdminLogger.errorAdmin( message, keyStr, nfe );
}
handlerCopy( request, response, session, admin, formItems, user, key );
}
else if ( "import".equals( operation ) )
{
throw new IllegalArgumentException( "Unsupported operation: import" );
}
else if ( "browse".equals( operation ) )
{
handlerBrowse( request, response, session, admin, formItems, parameters, user, verticalDoc );
}
else if ( "select".equals( operation ) )
{
handlerSelect( request, response, session, admin, formItems );
}
else if ( "show".equals( operation ) )
{
handlerShow( request, response, session, admin, formItems );
}
else if ( "form".equals( operation ) )
{
this.clearErrors();
handlerForm( request, response, session, admin, formItems );
}
else if ( "searchform".equals( operation ) )
{
handlerSearch( request, response, session, admin, formItems );
}
else if ( "searchresults".equals( operation ) )
{
handlerSearchResults( request, response, session, admin, formItems );
}
else if ( "report".equals( operation ) )
{
String subOp = formItems.getString( "subop" );
handlerReport( request, response, session, admin, formItems, subOp );
}
else if ( "closewindow".equals( operation ) )
{
closeWindow( response );
}
else if ( "preview".equals( operation ) )
{
handlerPreview( request, response, session, admin, formItems );
}
else if ( "menu".equals( operation ) )
{
handlerMenu( request, response, session, admin, formItems, parameters, user, verticalDoc );
}
else if ( "notify".equals( operation ) )
{
handlerNotify( request, response, session, admin, formItems, user );
}
else if ( "wizard".equals( operation ) )
{
String wizardName = formItems.getString( "name" );
handlerWizard( request, response, session, admin, formItems, parameters, user, wizardName );
}
else if ( operation != null )
{
handlerCustom( request, response, session, admin, formItems, operation, parameters, user, verticalDoc );
}
else
{
handlerCustom( request, response, session, admin, formItems, "missing" );
}
}
catch ( Exception e )
{
try
{
if ( !( e instanceof VerticalException ) && !( e instanceof VerticalRuntimeException ) )
{
String message = "Unexpected error occurred during handling of admin page: %t";
VerticalAdminLogger.error( message, e );
}
ErrorPageServlet.Error error = new ErrorPageServlet.ThrowableError( e );
session.setAttribute( "com.enonic.vertical.error", error );
redirectClientToAdminPath( "errorpage", (MultiValueMap) null, request, response );
}
catch ( VerticalAdminException vae )
{
String message = "Failed to redirect to error page: %t";
VerticalAdminLogger.errorAdmin( message, vae );
}
}
}
}
}
protected void transformXML( HttpServletRequest request, HttpServletResponse response, Document doc, Source xslSource,
Map<String, Object> parameters )
throws VerticalAdminException
{
final HttpSession session = request.getSession();
final String languageCode = (String) session.getAttribute( "languageCode" );
final URIResolver uriResolver = AdminStore.getURIResolver( languageCode );
new AdminXsltProcessorHelper( this.xsltProcessorFactory ).stylesheet( xslSource, uriResolver ).input( doc ).params( parameters ).process( response );
}
protected void transformXML( HttpServletRequest request, HttpServletResponse response, org.jdom.Document doc, Source xslSource,
Map<String, Object> parameters )
throws VerticalAdminException
{
final HttpSession session = request.getSession();
final String languageCode = (String) session.getAttribute( "languageCode" );
final URIResolver uriResolver = AdminStore.getURIResolver( languageCode );
new AdminXsltProcessorHelper( this.xsltProcessorFactory ).stylesheet( xslSource, uriResolver ).input( doc ).params( parameters ).process(
response );
}
protected void transformXML( HttpServletRequest request, HttpServletResponse response, Document doc, String xslPath, Map parameters )
throws VerticalAdminException
{
try
{
final HttpSession session = request.getSession();
final String languageCode = (String) session.getAttribute( "languageCode" );
final Source xslDoc = AdminStore.getStylesheet( languageCode, xslPath );
final URIResolver uriResolver = AdminStore.getURIResolver( languageCode );
new AdminXsltProcessorHelper( this.xsltProcessorFactory ).stylesheet( xslDoc, uriResolver ).input( doc ).params( parameters ).process( response );
}
catch ( XsltProcessorException xpe )
{
String msg = "Failed to transform xml: %t";
VerticalAdminLogger.errorAdmin( msg, xpe );
}
}
protected void transformXML( HttpServletRequest request, HttpServletResponse response, org.jdom.Document doc, String xslPath,
Map<String, Object> parameters )
throws VerticalAdminException
{
final HttpSession session = request.getSession();
final String languageCode = (String) session.getAttribute( "languageCode" );
final Source xslSource = AdminStore.getStylesheet( languageCode, xslPath );
transformXML( request, response, doc, xslSource, parameters );
}
protected void transformXML( HttpSession session, Writer writer, Source xmlSource, Source xslSource, Map<String, Object> parameters )
throws TransformerException
{
final String languageCode = (String) session.getAttribute( "languageCode" );
final URIResolver uriResolver = AdminStore.getURIResolver( languageCode );
new AdminXsltProcessorHelper( this.xsltProcessorFactory ).stylesheet( xslSource, uriResolver ).input( xmlSource ).params( parameters, false ).process( writer );
}
protected URIResolver getStylesheetURIResolver( final AdminService adminBean )
{
return new URIResolver()
{
public Source resolve( String href, String base )
throws TransformerException
{
Source source = null;
ResourceKey key = ResourceKey.from( href );
ResourceFile res = resourceService.getResourceFile( key );
if ( res != null )
{
String xsl = res.getDataAsString();
source = new StreamSource( new StringReader( xsl ) );
}
return source;
}
};
}
protected String buildAccessRightsXML( ExtendedMap formItems )
{
return buildAccessRightsXML( null, formItems, Integer.MIN_VALUE );
}
protected String buildAccessRightsXML( String key, ExtendedMap formItems, int accessrightsType )
{
Document doc = buildAccessRightsXML( null, key, formItems, accessrightsType );
if ( doc != null )
{
return XMLTool.documentToString( doc );
}
return null;
}
public static final Document buildAccessRightsXML( Element rootElem, String key, ExtendedMap formItems, int accessrightsType )
{
// Handle this in calling methods instead
//if (!formItems.containsKey("updateaccessrights"))
// return null;
Document doc;
Element elmAccessRights;
if ( rootElem != null )
{
doc = rootElem.getOwnerDocument();
elmAccessRights = XMLTool.createElement( doc, rootElem, "accessrights" );
}
else
{
doc = XMLTool.createDocument( "accessrights" );
elmAccessRights = doc.getDocumentElement();
}
if ( key != null )
{
elmAccessRights.setAttribute( "key", key );
}
if ( accessrightsType != Integer.MIN_VALUE )
{
elmAccessRights.setAttribute( "type", String.valueOf( accessrightsType ) );
}
for ( Object parameterKey : formItems.keySet() )
{
String paramName = (String) parameterKey;
if ( paramName.startsWith( "accessright[key=" ) )
{
String paramValue = formItems.getString( paramName );
ExtendedMap paramsInName = ParamsInTextParser.parseParamsInText( paramName, "[", "]", ";" );
ExtendedMap paramsInValue = ParamsInTextParser.parseParamsInText( paramValue, "[", "]", ";" );
buildAccessRightElement( doc, elmAccessRights, paramsInName.getString( "key" ), paramsInValue );
}
}
return doc;
}
protected static final Element buildAccessRightElement( Document doc, Element root, String key, ExtendedMap paramsInValue )
{
Element element = XMLTool.createElement( doc, root, "accessright" );
if ( key != null )
{
element.setAttribute( "groupkey", key );
}
element.setAttribute( "grouptype", paramsInValue.getString( "grouptype", "" ) );
element.setAttribute( "adminread", paramsInValue.getString( "adminread", "false" ) );
element.setAttribute( "read", paramsInValue.getString( "read", "false" ) );
element.setAttribute( "update", paramsInValue.getString( "update", "false" ) );
element.setAttribute( "delete", paramsInValue.getString( "delete", "false" ) );
element.setAttribute( "create", paramsInValue.getString( "create", "false" ) );
element.setAttribute( "publish", paramsInValue.getString( "publish", "false" ) );
element.setAttribute( "administrate", paramsInValue.getString( "administrate", "false" ) );
element.setAttribute( "approve", paramsInValue.getString( "approve", "false" ) );
element.setAttribute( "add", paramsInValue.getString( "add", "false" ) );
String displayName = paramsInValue.getString( "name", null );
if ( displayName != null )
{
element.setAttribute( "displayname", displayName );
}
return element;
}
protected CategoryAccessControl parseCategoryAccessControl( ExtendedMap categoryAccessRight )
{
CategoryAccessControl categoryAccessControl = new CategoryAccessControl();
categoryAccessControl.setReadAccess( categoryAccessRight.getBoolean( "read", false ) );
categoryAccessControl.setAdminBrowseAccess( categoryAccessRight.getBoolean( "adminread", false ) );
categoryAccessControl.setPublishAccess( categoryAccessRight.getBoolean( "publish", false ) );
categoryAccessControl.setCreateAccess( categoryAccessRight.getBoolean( "create", false ) );
categoryAccessControl.setAdminAccess( categoryAccessRight.getBoolean( "administrate", false ) );
return categoryAccessControl;
}
protected List<CategoryAccessControl> parseCategoryAccessRights( ExtendedMap formItems )
{
List<CategoryAccessControl> list = new ArrayList<CategoryAccessControl>();
for ( Object parameterKey : formItems.keySet() )
{
String paramName = (String) parameterKey;
if ( paramName.startsWith( "accessright[key=" ) )
{
CategoryAccessControl accessRight = new CategoryAccessControl();
String paramValue = formItems.getString( paramName );
ExtendedMap paramsInName = ParamsInTextParser.parseParamsInText( paramName, "[", "]", ";" );
ExtendedMap paramsInValue = ParamsInTextParser.parseParamsInText( paramValue, "[", "]", ";" );
if ( paramsInName.containsKey( "key" ) )
{
accessRight.setGroupKey( new GroupKey( paramsInName.getString( "key" ) ) );
}
if ( paramsInValue.containsKey( "administrate" ) )
{
accessRight.setAdminAccess( paramsInValue.getBoolean( "administrate" ) );
}
if ( paramsInValue.containsKey( "publish" ) )
{
accessRight.setPublishAccess( paramsInValue.getBoolean( "publish" ) );
}
if ( paramsInValue.containsKey( "create" ) )
{
accessRight.setCreateAccess( paramsInValue.getBoolean( "create" ) );
}
if ( paramsInValue.containsKey( "adminread" ) )
{
accessRight.setAdminBrowseAccess( paramsInValue.getBoolean( "adminread" ) );
}
if ( paramsInValue.containsKey( "read" ) )
{
accessRight.setReadAccess( paramsInValue.getBoolean( "read" ) );
}
list.add( accessRight );
}
}
return list;
}
public void addAccessLevelParameters( User user, Map<String, Object> parameters )
{
UserEntity userEntity = userDao.findByKey( user.getKey() );
UserKey userKey = user.getKey();
UserStoreKey userStoreKey = userEntity.getUserStoreKey();
boolean hasEnterpriseAdminPowers = memberOfResolver.hasEnterpriseAdminPowers( userKey );
boolean hasAdministratorPowers = memberOfResolver.hasAdministratorPowers( userKey );
boolean hasDeveloperPowers = memberOfResolver.hasDeveloperPowers( userKey );
boolean hasExpertContributorPowers = memberOfResolver.hasExpertContributorPowers( userKey );
boolean hasContributorPowers = memberOfResolver.hasContributorPowers( userKey );
boolean hasUserStoreAdministratorPowers = memberOfResolver.hasUserStoreAdministratorPowers( userKey, userStoreKey );
parameters.put( "userKey", String.valueOf( user.getKey() ) );
parameters.put( "enterpriseadmin", ( hasEnterpriseAdminPowers ? "true" : "false" ) );
parameters.put( "siteadmin", ( hasAdministratorPowers ? "true" : "false" ) );
parameters.put( "sitecontributor", ( hasContributorPowers ? "true" : "false" ) );
parameters.put( "expertcontributor", ( hasExpertContributorPowers ? "true" : "false" ) );
parameters.put( "developer", ( hasDeveloperPowers ? "true" : "false" ) );
parameters.put( "userstoreadmin", ( hasUserStoreAdministratorPowers ? "true" : "false" ) );
}
public int getDomainKey( HttpSession session )
{
int domainKey = -1;
String strDomainKey = (String) session.getAttribute( "selecteddomainkey" );
try
{
domainKey = Integer.parseInt( strDomainKey );
}
catch ( NumberFormatException e )
{
}
return domainKey;
}
protected void browseRedirectWithSorting( HttpServletRequest request, HttpServletResponse response, HttpSession session,
ExtendedMap formItems )
{
MultiValueMap queryParams = new MultiValueMap();
String page = formItems.getString( "page" );
queryParams.put( "page", page );
queryParams.put( "op", "browse" );
queryParams.put( "menukey", formItems.get( "menukey" ) );
String sortby = getSortBy( page, "browse" );
queryParams.put( "sortby", session.getAttribute( sortby ) );
String direction = getSortByDirection( page, "browse" );
queryParams.put( "sortby-direction", session.getAttribute( direction ) );
redirectClientToAdminPath( "adminpage", queryParams, request, response );
}
protected static String getSortBy( String page, String op )
{
StringBuilder sb_sortByKey = new StringBuilder( "s[page=" );
sb_sortByKey.append( page );
sb_sortByKey.append( ",op=" );
sb_sortByKey.append( op );
sb_sortByKey.append( ",s]" );
return sb_sortByKey.toString();
}
protected static String getSortByDirection( String page, String op )
{
StringBuilder sb_sortByDirectionKey = new StringBuilder( "s[page=" );
sb_sortByDirectionKey.append( page );
sb_sortByDirectionKey.append( ",op=" );
sb_sortByDirectionKey.append( op );
sb_sortByDirectionKey.append( ",sd]" );
return sb_sortByDirectionKey.toString();
}
protected void addSortParamteres( String defaultSortBy, String defaultSortByDirection, ExtendedMap inParams, HttpSession session,
HashMap<String, Object> outParams )
{
// Get choosen sort by user
String sortBy = inParams.getString( "sortby", null );
String sortByDirection = inParams.getString( "sortby-direction", null );
String page = inParams.getString( "page" );
String op = inParams.getString( "op" );
// s[page="+page+",op=browse,s]
String sortByKey = getSortBy( page, op );
// s[page="+page+",op=browse,sd]
String sortByDirectionKey = getSortByDirection( page, op );
//("sortByKey = " + sortByKey);
//("sortByDirectionKey = " + sortByDirectionKey);
// There is no choosen sort by user, get last sort from session
if ( sortBy == null || sortByDirection == null )
{
sortBy = (String) session.getAttribute( sortByKey );
sortByDirection = (String) session.getAttribute( sortByDirectionKey );
// If there is no last sort from session, use default
if ( sortBy == null )
{
sortBy = defaultSortBy;
}
if ( sortByDirection == null )
{
sortByDirection = defaultSortByDirection;
}
}
// User have specified a sort-direction, store it until next time
else
{
// Hack in order to sort timestamp columns in descending direction by default
if ( "timestamp".equals( sortBy ) )
{
if ( !"timestamp".equals( session.getAttribute( sortByKey ) ) )
{
sortByDirection = "descending";
}
}
else if ( "/content/@timestamp".equals( sortBy ) )
{
if ( !"/content/@timestamp".equals( session.getAttribute( sortByKey ) ) )
{
sortByDirection = "DESC";
}
}
session.setAttribute( sortByKey, sortBy );
session.setAttribute( sortByDirectionKey, sortByDirection );
}
outParams.put( "sortby", sortBy );
outParams.put( "sortby-direction", sortByDirection );
}
protected Document buildChangedAccessRightsXML( ExtendedMap formItems )
{
Document doc = XMLTool.createDocument( "changedaccessrights" );
Element changed = doc.getDocumentElement();
// Lager xml for diffen - de som er fjernet
for ( Object parameterKey : formItems.keySet() )
{
String paramName = (String) parameterKey;
if ( paramName.startsWith( "original_accessright[key=" ) )
{
ExtendedMap paramsInName = ParamsInTextParser.parseParamsInText( paramName, "[", "]", ";" );
String key = paramsInName.getString( "key" );
if ( !formItems.containsKey( "accessright[key=" + key + "]" ) )
{
String paramValue = formItems.getString( paramName );
ExtendedMap paramsInValue = ParamsInTextParser.parseParamsInText( paramValue, "[", "]", ";" );
Element elmAccessRight = buildAccessRightElement( doc, changed, key, paramsInValue );
elmAccessRight.setAttribute( "diffinfo", "removed" );
}
}
}
// Lager xml for diffen - de som er lagt til
for ( Object parameterKey : formItems.keySet() )
{
String paramName = (String) parameterKey;
if ( paramName.startsWith( "accessright[key=" ) )
{
ExtendedMap paramsInName = ParamsInTextParser.parseParamsInText( paramName, "[", "]", ";" );
String key = paramsInName.getString( "key" );
if ( !formItems.containsKey( "original_accessright[key=" + key + "]" ) )
{
String paramValue = formItems.getString( paramName );
ExtendedMap paramsInValue = ParamsInTextParser.parseParamsInText( paramValue, "[", "]", ";" );
Element elmAccessRight = buildAccessRightElement( doc, changed, key, paramsInValue );
elmAccessRight.setAttribute( "diffinfo", "added" );
}
}
}
// Lager xml for diffen - de som er endret
for ( Object paramKey : formItems.keySet() )
{
String paramName = (String) paramKey;
if ( paramName.startsWith( "accessright[key=" ) )
{
ExtendedMap paramsInName = ParamsInTextParser.parseParamsInText( paramName, "[", "]", ";" );
String key = paramsInName.getString( "key" );
if ( formItems.containsKey( "original_accessright[key=" + key + "]" ) )
{
String originalValue = formItems.getString( "original_accessright[key=" + key + "]" );
String currentValue = formItems.getString( paramName );
if ( !currentValue.equals( originalValue ) )
{
ExtendedMap paramsInValue = ParamsInTextParser.parseParamsInText( currentValue, "[", "]", ";" );
Element elmAccessRight = buildAccessRightElement( doc, changed, key, paramsInValue );
elmAccessRight.setAttribute( "diffinfo", "modified" );
}
}
}
}
return doc;
}
protected Document applyChangesInAccessRights( Document docExistingAccessRights, Map<String, ExtendedMap> removedAccessRights,
Map<String, ExtendedMap> modifiedAccessRights,
Map<String, ExtendedMap> addedAccessRights )
{
// We have to make a clone of this hashtable, because we may have to remove some elements
// and we don't want to affect this on the original hashtable.
addedAccessRights = new HashMap<String, ExtendedMap>( addedAccessRights );
//("removedAccessRights = " + removedAccessRights);
//("modifiedAccessRights = " + modifiedAccessRights);
//("addedAccessRights = " + addedAccessRights);
Element elExistingAccessRights = docExistingAccessRights.getDocumentElement();
//("antall accessrights: " + elExistingAccessRights.getChildNodes().getLength());
// Loop thru existing accessrights and check if there is anyone to remove or modify
Element curAccessRight = (Element) elExistingAccessRights.getFirstChild();
while ( curAccessRight != null )
{
String groupKey = curAccessRight.getAttribute( "groupkey" );
//("checking accessright, groupkey = " + groupKey);
boolean remove = removedAccessRights.containsKey( groupKey );
boolean modify = modifiedAccessRights.containsKey( groupKey );
boolean add = addedAccessRights.containsKey( groupKey );
boolean overwrite = ( modify || add );
// Remove accessright
if ( remove )
{
//("removing accessright, groupkey = " + groupKey);
curAccessRight = XMLTool.removeChildFromParent( elExistingAccessRights, curAccessRight );
}
// Overwrite accessright
else if ( overwrite )
{
ExtendedMap params;
if ( modify )
{
params = modifiedAccessRights.get( groupKey );
//("modifying/overwriting accessright, groupkey = " + groupKey);
}
else // add == true:
{
params = addedAccessRights.get( groupKey );
//("adding/overwriting accessright, groupkey = " + groupKey);
}
Document docNewAccessRight = XMLTool.createDocument( "foo" );
Element elNewAccessRight =
buildAccessRightElement( docNewAccessRight, docNewAccessRight.getDocumentElement(), groupKey, params );
Element imported = (Element) docExistingAccessRights.importNode( elNewAccessRight, true );
elExistingAccessRights.replaceChild( imported, curAccessRight );
curAccessRight = imported;
// Hvis vi overskriver eksisterende rettighet i stedet for å legge til, fordi den finnes fra før
// må vi fjerne rettigheten fra addedAccessRights, slik at vi ikke legger til den to ganger.
if ( add )
{
//("Found an accessright that we wanted to add, that existed - we overwrite it
// inseated, and removes the groupkey ("+groupKey+")from the addAccessRights hashtable so that it
// want be added later");
addedAccessRights.remove( groupKey );
}
//
curAccessRight = (Element) curAccessRight.getNextSibling();
}
else
{
curAccessRight = (Element) curAccessRight.getNextSibling();
}
}
// Add new accessrights
for ( Object addedAccessRightKey : addedAccessRights.keySet() )
{
String currentGroupKey = (String) addedAccessRightKey;
//("adding new accessright, groupkey = " + currentGroupKey);
ExtendedMap params = addedAccessRights.get( currentGroupKey );
Document docNewAccessRight = XMLTool.createDocument( "foo" );
Element elNewAccessRight =
buildAccessRightElement( docNewAccessRight, docNewAccessRight.getDocumentElement(), currentGroupKey, params );
elExistingAccessRights.appendChild( docExistingAccessRights.importNode( elNewAccessRight, true ) );
}
return docExistingAccessRights;
}
public static int[] getIntArrayFormItem( ExtendedMap formItems, String formKey )
{
return getIntArrayFormItems( formItems, new String[]{formKey} );
}
public static int[] getIntArrayFormItems( ExtendedMap formItems, String[] formKeys )
{
TIntArrayList keys = new TIntArrayList();
for ( int i = 0; i < formKeys.length; i++ )
{
String[] items = getArrayFormItem( formItems, formKeys[i] );
for ( int j = 0; j < items.length; j++ )
{
if ( items[j] != null && items[j].length() > 0 )
{
int value = Integer.parseInt( items[j] );
if ( !keys.contains( value ) )
{
keys.add( value );
}
}
}
}
return keys.toArray();
}
protected void addPageTemplatesOfUserSitesToDocument( AdminService admin, UserEntity user, PageTemplateType allowedPageTemplateType,
Document verticalDoc )
{
final Document doc = XMLTool.createDocument( "pagetemplates-in-sites" );
Document sitesUserHaveAccessToDoc = admin.getAdminMenu( user, -1 ).getAsDOMDocument();
Element[] allSiteElements = XMLTool.getElements( sitesUserHaveAccessToDoc.getDocumentElement() );
for ( Element siteElement : allSiteElements )
{
final int siteKey = Integer.valueOf( siteElement.getAttribute( "key" ) );
final Document supportedPageTemplatesOfSite = getSupportedPageTemplatesOfSite( siteKey, allowedPageTemplateType );
XMLTool.mergeDocuments( doc, supportedPageTemplatesOfSite, true );
}
XMLTool.mergeDocuments( verticalDoc, doc, true );
}
protected Document getSupportedPageTemplatesOfSite( int siteKey, PageTemplateType allowedPageTemplateType )
{
final Document doc = XMLTool.createDocument( "pagetemplates-in-site" );
final Element rootEl = doc.getDocumentElement();
rootEl.setAttribute( "site", String.valueOf( siteKey ) );
final SiteEntity site = siteDao.findByKey( siteKey );
final Set<PageTemplateEntity> pageTemplates = site.getPageTemplates();
final PageTemplateSpecification pageTemplateSpecification = new PageTemplateSpecification();
pageTemplateSpecification.setType( allowedPageTemplateType );
for ( PageTemplateEntity pageTemplate : pageTemplates )
{
if ( pageTemplateSpecification.satisfies( pageTemplate ) )
{
final Element elem = XMLTool.createElement( doc, rootEl, "pagetemplate" );
elem.setAttribute( "key", String.valueOf( pageTemplate.getKey() ) );
final Element contentTypesEl = XMLTool.createElement( doc, elem, "contenttypes" );
for ( ContentTypeEntity contentTypeEntity : pageTemplate.getContentTypes() )
{
final Element contentTypeEl = XMLTool.createElement( doc, contentTypesEl, "contenttype" );
contentTypeEl.setAttribute( "key", String.valueOf( contentTypeEntity.getKey() ) );
}
}
}
return doc;
}
protected String getDefaultDataSourceRootElementName()
{
return defaultDataSourceRootElementName;
}
@Value("${cms.admin.binaryUploadMaxSize}")
public void setMultiPartRequestMaxSize( final long value )
{
this.multiPartRequestMaxSize = value;
}
@Value("${cms.datasource.defaultResultRootElement}")
public void setDefaultDataSourceRootElementName( final String defaultDataSourceRootElementName )
{
this.defaultDataSourceRootElementName = defaultDataSourceRootElementName;
}
@Value("${cms.xml.storeXHTML}")
public void setStoreXHTML( final String storeXHTML )
{
this.storeXHTML = storeXHTML;
}
private static class ErrorCode
{
int code;
String name;
String value;
protected ErrorCode( int errorCode, String fieldName, String fieldValue )
{
code = errorCode;
name = fieldName;
value = fieldValue;
}
}
}