package com.processpuzzle.artifact_management.control; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.processpuzzle.application.configuration.domain.ProcessPuzzleContext; import com.processpuzzle.application.control.control.CommandDispatcher; import com.processpuzzle.application.control.control.CommandInterface; import com.processpuzzle.application.security.control.AuthorizationException; import com.processpuzzle.application.security.domain.User; import com.processpuzzle.artifact.domain.Artifact; import com.processpuzzle.artifact.domain.ArtifactFactory; import com.processpuzzle.artifact.domain.ArtifactFolder; import com.processpuzzle.artifact.domain.ArtifactFolderRepository; import com.processpuzzle.artifact.domain.DefaultArtifactRepository; import com.processpuzzle.artifact_type.domain.ArtifactType; import com.processpuzzle.artifact_type.domain.ArtifactTypeRepository; import com.processpuzzle.artifact_type.domain.PropertyDefinition; import com.processpuzzle.persistence.domain.EntityIdentityCollitionException; import com.processpuzzle.persistence.domain.DefaultUnitOfWork; import com.processpuzzle.user_session.domain.UserRequestManager; public class CreateArtifactCommand implements CommandInterface { public static final String COMMAND_NAME = "CreateArtifact"; public static final String ARTIFACT_TYPE_NAME_PARAM = "artifactTypeName"; public static final String ARTIFACT_FOLDER_NAME_PARAM = "artifactFolderName"; public static final String ARTIFACT_NAME_PARAM = "artifactName"; private static final String CONSTRUCTION_METHOD_NAME = "create"; private String artifactTypeName; private String artifactFolderName; private String artifactName; protected ArtifactFolder artifactFolder; private ArtifactType subjectArtifactType; private Artifact<?> subjectArtifact; private User loggedInUser; protected XmlActionResponse actionResponse; protected CommandDispatcher dispatcher; private ArtifactFolderRepository artifactFolderRepository; private ProcessPuzzleContext applicationContext; private DefaultArtifactRepository artifactRepository; private ArtifactTypeRepository artifactTypeRepository; private String errorDescription; public String execute( CommandDispatcher dispatcher ) throws Exception { doAction(); buildResponse( dispatcher ); return ""; } public void init( CommandDispatcher dispatcher ) { applicationContext = UserRequestManager.getInstance().getApplicationContext(); artifactFolderRepository = applicationContext.getRepository( ArtifactFolderRepository.class ); artifactTypeRepository = (ArtifactTypeRepository) applicationContext.getRepository( ArtifactTypeRepository.class ); artifactRepository = (DefaultArtifactRepository) applicationContext.getRepository( DefaultArtifactRepository.class ); this.dispatcher = dispatcher; retrieveRequestParameters( dispatcher.getRequest() ); findSubjectObjects(); loggedInUser = UserRequestManager.getInstance().currentUser(); // LoggedUserLocator.locate( dispatcher ); if( loggedInUser == null ) throw new AuthorizationException( "Unknown", CreateArtifactCommand.class.getSimpleName() ); setUpResponse(); } public String getName() { return COMMAND_NAME; } protected void buildResponse( CommandDispatcher dispatcher ) throws IOException { HttpServletResponse response = dispatcher.getResponse(); response.setContentType( "text/xml" ); response.setCharacterEncoding( "UTF-8" ); response.setHeader( "Cache-Control", "no-cache" ); response.getWriter().write( actionResponse.getAsString() ); } protected void doAction() { if( subjectArtifactType != null ){ boolean isFolder = (subjectArtifactType.getName().equals( "ArtifactFolder" )); DefaultUnitOfWork work = new DefaultUnitOfWork( true ); determineContainingFolder( work ); List<Class<?>> parameterTypes = new ArrayList<Class<?>>(); List<Object> parameterValues = new ArrayList<Object>(); determineCreationParameters( isFolder, parameterTypes, parameterValues ); subjectArtifact = instantiateAndSaveNewArtifact( parameterTypes, parameterValues, isFolder, work ); artifactName = subjectArtifact.getName(); defineCreationResponse( parameterValues.toArray() ); work.finish(); }else{ defineErroneousResponse(); } } protected void retrieveRequestParameters( HttpServletRequest request ) { artifactTypeName = (String) request.getParameter( ARTIFACT_TYPE_NAME_PARAM ); artifactFolderName = (String) request.getParameter( ARTIFACT_FOLDER_NAME_PARAM ); artifactName = (String) request.getParameter( ARTIFACT_NAME_PARAM ); } private void defineErroneousResponse() { String errorDescription; errorDescription = "<errorDescription>" + "unknownArtifactType" + "</errorDescription>"; errorDescription += "<parameter>" + artifactTypeName + "</parameter>"; actionResponse.addStringToBody( errorDescription ); actionResponse.setOutcome( false ); } private void defineCreationResponse( Object[] propertyValues ) { if( errorDescription != null ){ errorDescription = "<errorDescription>" + errorDescription + "</errorDescription>"; for( int j = 1; j < propertyValues.length; j++ ){ errorDescription += "<parameter>" + propertyValues[j] + "</parameter>"; } actionResponse.addStringToBody( errorDescription ); actionResponse.setOutcome( false ); }else actionResponse.setOutcome( true ); } private void determineContainingFolder( DefaultUnitOfWork work ) { String folderPath = subjectArtifactType.getInstanceFolderPath(); artifactFolder = artifactFolderRepository.findByPath( work, folderPath ); } private void determineCreationParameters( boolean isFolder, List<Class<?>> parameterTypes, List<Object> parameterValues ) { Collection<PropertyDefinition> properties = subjectArtifactType.getPropertyDefinitions(); try{ for( Iterator<PropertyDefinition> iter = properties.iterator(); iter.hasNext(); ){ PropertyDefinition propertyDefinition = (PropertyDefinition) iter.next(); Object parameterValue = getRequestParameterByName( propertyDefinition.getName() ); if( parameterValue == null ) throw new IllegalArgumentException( "Artifact creation parameter: " + propertyDefinition.getName() + "not found in request." ); Class<?> parameterType = Class.forName( propertyDefinition.getType().getJavaClassName() ); parameterTypes.add( parameterType ); parameterValues.add( parameterValue ); } if( isFolder ){ parameterTypes.add( ArtifactFolder.class ); parameterValues.add( artifactFolder ); } }catch( SecurityException e ){ errorDescription = "error"; }catch( IllegalArgumentException e ){ errorDescription = "illegalArgument"; }catch( EntityIdentityCollitionException e ){ errorDescription = "entityIdentityCollition"; }catch( AuthorizationException e ){ errorDescription = "permissionDenied"; }catch( ClassNotFoundException e ){ errorDescription = "classNotFound"; } } @SuppressWarnings( "unchecked" ) private Artifact<?> instantiateAndSaveNewArtifact( List<Class<?>> paramTypes, List<Object> paramValues, boolean isFolder, DefaultUnitOfWork work ) { Artifact<?> newArtifact = null; Class<?>[] parameterTypes = new Class<?>[paramTypes.size()]; Object[] parameterValues = paramValues.toArray(); int i = 0; for( Class<?> parameterType : paramTypes ){ parameterTypes[i] = parameterType; i++; } try{ Class<? extends Artifact<?>> artifactClass = (Class<? extends Artifact<?>>) Class.forName( subjectArtifactType .getArtifactClassName() ); ArtifactFactory<?> factory = (ArtifactFactory<?>) applicationContext.getEntityFactoryByEntityClass( artifactClass ); Method createMethod = factory.getClass().getDeclaredMethod( CONSTRUCTION_METHOD_NAME, parameterTypes ); newArtifact = (Artifact<?>) createMethod.invoke( factory, parameterValues ); }catch( ClassNotFoundException e ){ errorDescription = "unknownArtifactClass"; }catch( NoSuchMethodException e ){ errorDescription = "error"; }catch( IllegalAccessException e ){ errorDescription = "error"; }catch( InvocationTargetException e ){ errorDescription = "invocationTarget"; } if( !isFolder && artifactFolder == null ) errorDescription = "missingFolder"; else if( artifactFolder != null ){ artifactFolder.addChildArtifact( newArtifact ); // save related artifacts for( Iterator<Artifact<?>> iter = newArtifact.getRelatedArtifacts().iterator(); iter.hasNext(); ){ Artifact<?> a = iter.next(); artifactFolder.addChildArtifact( a ); } artifactFolderRepository.update( work, artifactFolder ); actionResponse.addStringToBody( "<id>" + newArtifact.getId() + "</id>" ); }else if( artifactFolder == null && isFolder && artifactFolderRepository.findByPath( work, newArtifact.getName() ) == null ){ artifactRepository.add( work, newArtifact ); actionResponse.addStringToBody( "<id>" + newArtifact.getId() + "</id>" ); }else errorDescription = "artifactIsExist"; return newArtifact; } private void findSubjectObjects() { DefaultUnitOfWork work = new DefaultUnitOfWork( true ); subjectArtifactType = artifactTypeRepository.findArtifactTypeByName( work, artifactTypeName ); artifactFolder = (ArtifactFolder) artifactFolderRepository.findByPath( work, artifactFolderName ); work.finish(); } private String getRequestParameterByName( String name ) { return dispatcher.getRequest().getParameter( name ); } private void setUpResponse() { actionResponse = new XmlActionResponse(); } }