/***********************************************************************
 * Copyright (c) 2008 by SAP AG, Walldorf. 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     SAP AG - initial API and implementation
 *     Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation
 ***********************************************************************/
package org.eclipse.jpt.ui.internal.wizards.entity.data.operation;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.codegen.jet.JETEmitter;
import org.eclipse.emf.codegen.jet.JETException;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaModelMarker;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jpt.core.JptCorePlugin;
import org.eclipse.jpt.core.internal.resource.orm.OrmResourceModelProvider;
import org.eclipse.jpt.core.internal.resource.persistence.PersistenceResourceModelProvider;
import org.eclipse.jpt.core.resource.orm.AccessType;
import org.eclipse.jpt.core.resource.orm.Attributes;
import org.eclipse.jpt.core.resource.orm.Inheritance;
import org.eclipse.jpt.core.resource.orm.InheritanceType;
import org.eclipse.jpt.core.resource.orm.OrmFactory;
import org.eclipse.jpt.core.resource.orm.OrmPackage;
import org.eclipse.jpt.core.resource.orm.OrmResource;
import org.eclipse.jpt.core.resource.orm.XmlEntity;
import org.eclipse.jpt.core.resource.orm.XmlEntityMappings;
import org.eclipse.jpt.core.resource.orm.XmlIdClass;
import org.eclipse.jpt.core.resource.orm.XmlIdImpl;
import org.eclipse.jpt.core.resource.orm.XmlMappedSuperclass;
import org.eclipse.jpt.core.resource.orm.XmlTable;
import org.eclipse.jpt.core.resource.persistence.PersistenceFactory;
import org.eclipse.jpt.core.resource.persistence.PersistenceResource;
import org.eclipse.jpt.core.resource.persistence.XmlJavaClassRef;
import org.eclipse.jpt.core.resource.persistence.XmlMappingFileRef;
import org.eclipse.jpt.core.resource.persistence.XmlPersistence;
import org.eclipse.jpt.core.resource.persistence.XmlPersistenceUnit;
import org.eclipse.jpt.ui.JptUiPlugin;
import org.eclipse.jpt.ui.internal.wizards.entity.AnnotatedEntityTemplate;
import org.eclipse.jpt.ui.internal.wizards.entity.EntityTemplate;
import org.eclipse.jpt.ui.internal.wizards.entity.EntityWizardMsg;
import org.eclipse.jpt.ui.internal.wizards.entity.IdClassTemplate;
import org.eclipse.jpt.ui.internal.wizards.entity.data.model.CreateEntityTemplateModel;
import org.eclipse.jst.common.internal.annotations.controller.AnnotationsController;
import org.eclipse.jst.common.internal.annotations.controller.AnnotationsControllerManager;
import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.WTPJETEmitter;
import org.eclipse.wst.common.componentcore.internal.operation.ArtifactEditProviderOperation;
import org.eclipse.wst.common.componentcore.internal.operation.IArtifactEditOperationDataModelProperties;
import org.eclipse.wst.common.frameworks.datamodel.AbstractDataModelOperation;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.enablement.nonui.WFTWrappedException;
import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;

/**
 * The NewEntityClassOperation is IDataModelOperation following the
 * IDataModel wizard and operation framework.
 * 
 * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelOperation
 * @see org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider
 * 
 * This operation is used to generate java classes for the new JPA entity. It uses 
 * EntityDataModelProvider to store the appropriate properties required to generate the new entity. 
 * @see org.eclipse.jpt.ui.internal.wizards.entity.data.modelEntityDataModelProvider
 * 
 * A WTPJetEmitter entity template is used to create the class with the entity template. 
 * @see org.eclipse.jst.j2ee.internal.project.WTPJETEmitter
 * @see org.eclipse.jpt.ui.internal.wizards.entity.data.model.CreateEntityTemplateModel
 * 
 * The use of this class is EXPERIMENTAL and is subject to substantial changes.
 */
public class NewEntityClassOperation extends AbstractDataModelOperation {

	private static final String DOT_JAVA = ".java"; //$NON-NLS-1$
	private static final String SEPARATOR = "/";//$NON-NLS-1$
	private static final String VERSION_STRING = "1.0";//$NON-NLS-1$
	private static final String FIELD = "FIELD";//$NON-NLS-1$
	private static final String PROPERTY = "PROPERTY";//$NON-NLS-1$	
	protected static final String WTP_CUSTOMIZATION_PLUGIN = "WTP_CUSTOMIZATION_PLUGIN"; //$NON-NLS-1$
	protected static final String ANNOTATED_ENTITY_TEMPLATE_FILE = "/templates/annotated_entity.javajet"; //$NON-NLS-1$	
	protected static final String ENTITY_TEMPLATE_FILE = "/templates/entity.javajet"; //$NON-NLS-1$
	protected static final String IDCLASS_TEMPLATE_FILE = "/templates/idClass.javajet"; //$NON-NLS-1$	
	protected static final String BUILDER_ID = "builderId"; //$NON-NLS-1$
	private static final String EMPTY_STRING = "";//$NON-NLS-1$
	private static final String SINGLE_TABLE = "SINGLE_TABLE";//$NON-NLS-1$
	
	/**
	 * Method name of template implementation classes. 
	 */
	protected static final String GENERATE_METHOD = "generate"; //$NON-NLS-1$

	/**
	 * This is the constructor which should be used when creating a NewEntityClassOperation. 
	 * An instance of the CreateEntityTemplateModel should be passed in. This does not accept
	 * null parameter. It will not return null.
	 * 
	 * @see ArtifactEditProviderOperation#ArtifactEditProviderOperation(IDataModel)
	 * @see CreateEntityTemplateModel
	 * 
	 * @param dataModel
	 * @return NewFilterClassOperation
	 */
	public NewEntityClassOperation(IDataModel dataModel) {
		super(dataModel);
	}

	/**
	 * The implementation of the execute method drives the running of the operation. 
	 * This implementation will create the java source folder, create the java package, and then 
	 * the entity (or mapped as superclass) and ID class files will be created using templates. 
	 * 
	 * @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
	 * @see NewEntityClassOperation#generateUsingTemplates(IProgressMonitor,
	 *      IPackageFragment)
	 * 
	 * @param monitor
	 * @throws CoreException
	 * @throws InterruptedException
	 * @throws InvocationTargetException
	 */
	public IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
		// Create source folder if it does not exist
		createJavaSourceFolder();
		// Create java package if it does not exist
		IPackageFragment pack = createJavaPackage();
		// Generate filter class using templates
		try {
			generateUsingTemplates(monitor, pack);
		} catch (Exception e) {
			return WTPCommonPlugin.createErrorStatus(e.toString());
		}
		return OK_STATUS;
	}

	/**
	 * This method will return the java package as specified by the new java
	 * class data model. If the package does not exist, it will create the
	 * package. This method should not return null.
	 * 
	 * @see INewJavaClassDataModelProperties#JAVA_PACKAGE
	 * @see IPackageFragmentRoot#createPackageFragment(java.lang.String,
	 *      boolean, org.eclipse.core.runtime.IProgressMonitor)
	 * 
	 * @return IPackageFragment the java package
	 */
	protected final IPackageFragment createJavaPackage() {
		// Retrieve the package name from the java class data model
		String packageName = model.getStringProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE);
		IPackageFragmentRoot packRoot = (IPackageFragmentRoot) model
				.getProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE_FRAGMENT_ROOT);
		IPackageFragment pack = packRoot.getPackageFragment(packageName);
		// Handle default package
		if (pack == null) {
			pack = packRoot.getPackageFragment(""); //$NON-NLS-1$
		}		
		
		// Create the package fragment if it does not exist
		if (!pack.exists()) {
			String packName = pack.getElementName();
			try {
				pack = packRoot.createPackageFragment(packName, true, null);
			} catch (JavaModelException e) {
				Logger.getLogger().log(e);
			}
		}
		// Return the package
		return pack;
	}

	/**
	 * This implementation uses the creation of a CreateEntityTemplateModel and the WTPJETEmitter
	 * to create the java class with the annotated tags. This method accepts null for monitor, it does not accept null 
	 * for fragment. If annotations are not being used the tags will be omitted from the class.
	 * 
	 * @see CreateEntityTemplateModel
	 * @see NewEntityClassOperation#generateTemplateSource(CreateEntityTemplateModel,
	 *      IProgressMonitor)
	 * 
	 * @param monitor
	 * @param fragment
	 * @throws CoreException
	 * @throws WFTWrappedException
	 */
	protected void generateUsingTemplates(IProgressMonitor monitor, IPackageFragment fragment) throws WFTWrappedException, CoreException {
	    // Create the entity template model
	    CreateEntityTemplateModel tempModel = createTemplateModel();
        IProject project = getTargetProject();
        String entityClassSource = null;
        String idClassSource = null;
        // Generate the java source based on the entity template models
        try {
        	if (tempModel.isArtifactsAnnotated()) {
        		AnnotatedEntityTemplate tempImpl = AnnotatedEntityTemplate.create(null);
        		entityClassSource = generateTemplateSource(tempModel, ANNOTATED_ENTITY_TEMPLATE_FILE, tempImpl, monitor);
        	} else {
        		EntityTemplate tempImpl = EntityTemplate.create(null);
        		entityClassSource = generateTemplateSource(tempModel, ENTITY_TEMPLATE_FILE, tempImpl, monitor);
        	}
            if (tempModel.isCompositePK()) {
            	IdClassTemplate tempImpl = IdClassTemplate.create(null);
            	idClassSource = generateTemplateSource(tempModel, IDCLASS_TEMPLATE_FILE, tempImpl, monitor);
            }
        } catch (Exception e) {
            throw new WFTWrappedException(e);
        }
        if (fragment != null) {
            // Create the java file
            String javaFileName = tempModel.getClassName() + DOT_JAVA;
            ICompilationUnit cu = fragment.getCompilationUnit(javaFileName);
            // Add the compilation unit to the java file
            if (cu == null || !cu.exists()) {
                cu = fragment.createCompilationUnit(javaFileName, entityClassSource, true, monitor);
            }
            IFile aFile = (IFile) cu.getResource();
            // Let the annotations controller process the annotated resource
            if (tempModel.isArtifactsAnnotated()) {
            	AnnotationsController controller = AnnotationsControllerManager.INSTANCE.getAnnotationsController(project);
            	if (controller != null) {
            		controller.process(aFile);
            	}
            }
            //Create IdClass if the primary key is complex
            if (idClassSource != null) {
                String entityPKName = tempModel.getIdClassName() + DOT_JAVA;
                ICompilationUnit cu1 = fragment.getCompilationUnit(entityPKName);
                // Add the compilation unit to the java file
                if (cu1 == null || !cu1.exists()) {
                    cu1 = fragment.createCompilationUnit(entityPKName, idClassSource, true, monitor);
                }           	
            }            
        }
                       
        if (!tempModel.isArtifactsAnnotated()) {
        	if (tempModel.isNonEntitySuperclass()) { 
        		addMappedSuperclassToXML(tempModel, project).schedule();
        	} else {
        		addEntityToXML(tempModel, project).schedule();
        	}
        }
        if (!tempModel.isMappingXMLDefault() || !JptCorePlugin.discoverAnnotatedClasses(project)) {
        	registerMappingXML(tempModel, project).schedule();
        }
	}

	/**
     * This method is intended for internal use only. This method will create an
     * instance of the CreateEntityTemplateModel model to be used in conjunction
     * with the WTPJETEmitter. This method will not return null.
     * 
     * @see CreateEntityTemplateModel
     * @see NewEntityClassOperation#generateUsingTemplates(IProgressMonitor,
     *      IPackageFragment)
     * 
     * @return CreateFilterTemplateModel
     */
    private CreateEntityTemplateModel createTemplateModel() {
        CreateEntityTemplateModel templateModel = new CreateEntityTemplateModel(model);
        return templateModel;
    }
    
    /**
     * This method is intended for internal use only. This will use the
     * WTPJETEmitter to create an annotated java file based on the passed template model. 
     * This method does not accept null parameters. It will not return null. 
     * If annotations are not used, it will use the non annotated template to omit the annotated tags.
     * 
     * @see NewEntityClassOperation#generateUsingTemplates(IProgressMonitor,
     *      IPackageFragment)
     * @see JETEmitter#generate(org.eclipse.core.runtime.IProgressMonitor,
     *      java.lang.Object[])
     * @see CreateEntityTemplateModel
     * 
     * @param templateModel
     * @param monitor
     * @param template_file 
     * @return String the source for the java file
     * @throws JETException
     * @throws NoSuchMethodException 
     * @throws SecurityException 
     * @throws InvocationTargetException 
     * @throws IllegalAccessException  
     */
    private String generateTemplateSource(CreateEntityTemplateModel templateModel, String templateFile, Object templateImpl, IProgressMonitor monitor) 
    		throws JETException, SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    	Preferences preferences = J2EEPlugin.getDefault().getPluginPreferences();
		boolean dynamicTranslation = preferences.getBoolean(J2EEPlugin.DYNAMIC_TRANSLATION_OF_JET_TEMPLATES_PREF_KEY);
		if (dynamicTranslation) {
	        URL templateURL = FileLocator.find(JptUiPlugin.getPlugin().getBundle(), new Path(templateFile), null);
	        cleanUpOldEmitterProject();
	        WTPJETEmitter emitter = new WTPJETEmitter(templateURL.toString(), this.getClass().getClassLoader());
	        emitter.setIntelligentLinkingEnabled(true);
	        emitter.addVariable(WTP_CUSTOMIZATION_PLUGIN, JptUiPlugin.PLUGIN_ID);
	        return emitter.generate(monitor, new Object[] { templateModel });
		} else {
			Method method = templateImpl.getClass().getMethod(GENERATE_METHOD, new Class[] { Object.class });
			return (String) method.invoke(templateImpl, templateModel);
		}
    }
    
	/**
	 * This method is intended for internal use only. It will clean up the old emmiter project 
	 * in order to prevent generation issues 
	 */
	private void cleanUpOldEmitterProject() {
		IProject project = ProjectUtilities.getProject(WTPJETEmitter.PROJECT_NAME);
		if (project == null || !project.exists())
			return;
		try {
			IMarker[] markers = project.findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO);
			for (int i = 0, l = markers.length; i < l; i++) {
				if (((Integer) markers[i].getAttribute(IMarker.SEVERITY)).intValue() == IMarker.SEVERITY_ERROR) {
					project.delete(true, new NullProgressMonitor());
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * This method will return the java source folder as specified in the java
	 * class data model. It will create the java source folder if it does not
	 * exist. This method may return null.
	 * 
	 * @see INewJavaClassDataModelProperties#SOURCE_FOLDER
	 * @see IFolder#create(boolean, boolean,
	 *      org.eclipse.core.runtime.IProgressMonitor)
	 * 
	 * @return IFolder the java source folder
	 */
	protected final IFolder createJavaSourceFolder() {
		// Get the source folder name from the data model
		String folderFullPath = model.getStringProperty(INewJavaClassDataModelProperties.SOURCE_FOLDER);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IFolder folder = root.getFolder(new Path(folderFullPath));
		// If folder does not exist, create the folder with the specified path
		if (!folder.exists()) {
			try {
				folder.create(true, true, null);
			} catch (CoreException e) {
				Logger.getLogger().log(e);
			}
		}
		// Return the source folder
		return folder;
	}

	@Override
	public IStatus execute(IProgressMonitor monitor, IAdaptable info)
			throws ExecutionException {
		return doExecute(monitor, info);
	}
	
	public IProject getTargetProject() {
		String projectName = model.getStringProperty(IArtifactEditOperationDataModelProperties.PROJECT_NAME);
		return ProjectUtilities.getProject(projectName);
	}	
		
	/**
	 * Adds entity to ORM XML in separate job
	 * @param model entity data model
	 * @param project JPA project in which the entity will be created
	 * @return
	 */
	private Job addEntityToXML(final CreateEntityTemplateModel model, final IProject project) {
		Job job = new Job(EntityWizardMsg.ADD_ENTITY_TO_XML) {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				final OrmResourceModelProvider modelProvider;
				if (model.isMappingXMLDefault()) {
					modelProvider = OrmResourceModelProvider.getDefaultModelProvider(project);
				}
				else {
					modelProvider = OrmResourceModelProvider.getModelProvider(project, model.getMappingXMLName());
				}
				modelProvider.modify(new Runnable() {
					public void run() {
						OrmResource resource = modelProvider.getResource();
						
						XmlEntityMappings entityMappings = resource.getEntityMappings();
						if (entityMappings == null) {
							entityMappings = OrmFactory.eINSTANCE.createXmlEntityMappings();
							entityMappings.setVersion(VERSION_STRING);
						}
	
						XmlEntity xmlEntity = OrmFactory.eINSTANCE.createXmlEntity();
						xmlEntity.setClassName(model.getQualifiedJavaClassName());
						if (model.isInheritanceSet()) {
							Inheritance inheritance = OrmFactory.eINSTANCE.createInheritance();
							String inheritanceStrategy = model.getInheritanceStrategyName();
							if (inheritanceStrategy.equals(EMPTY_STRING)) {
								inheritanceStrategy = SINGLE_TABLE;
							}
							InheritanceType inheritanceType = OrmFactory.eINSTANCE.createInheritanceTypeFromString(null, inheritanceStrategy);// TODO
							inheritance.setStrategy(inheritanceType);
							xmlEntity.setInheritance(inheritance);
						}
	
						if (model.isEntityNameSet()) {
							xmlEntity.setName(model.getEntityName());
						}
						if (model.isTableNameSet()) {
							XmlTable xmlTable = OrmFactory.eINSTANCE.createXmlTable();
							xmlTable.setName(model.getTableName());
							xmlEntity.setTable(xmlTable);
						}
						if (model.isCompositePK()) {
							XmlIdClass idClass = OrmFactory.eINSTANCE.createXmlIdClass();
							idClass.setClassName(model.getIdClassName());
							xmlEntity.setIdClass(idClass);
						}
						List<String> pkFields = model.getPKFields();
						if (pkFields.size() > 0) {
							Attributes entityAttributes = OrmFactory.eINSTANCE.createAttributes();
							List<XmlIdImpl> ids = new ArrayList<XmlIdImpl>();
							for (String fieldName : pkFields) {
								XmlIdImpl idImpl = OrmFactory.eINSTANCE.createXmlIdImpl();
								idImpl.setName(fieldName);
								ids.add(idImpl);
							}
							entityAttributes.eSet(OrmPackage.ATTRIBUTES__IDS, ids);
							xmlEntity.setAttributes(entityAttributes);
						}
	
						String accessTypeString = FIELD;
						if (!model.isFieldAccess()) {
							accessTypeString = PROPERTY;
						}
						AccessType accessType = OrmFactory.eINSTANCE.createAccessTypeFromString(null, accessTypeString);// TODO
						xmlEntity.setAccess(accessType);
						EList<XmlEntity> entities = entityMappings.getEntities();
						entities.add(xmlEntity);
						resource.getContents().add(entityMappings);
					}
				});
				return Status.OK_STATUS;
			}
		};
		return job;
	}

	/**
	 * Adds mapped superclass to ORM XML in separate job
	 * 
	 * @param model entity data model
	 * @param project JPA project in which the entity will be created
	 * @return the created job
	 */
	private Job addMappedSuperclassToXML(final CreateEntityTemplateModel model, final IProject project) {
		Job job = new Job(EntityWizardMsg.ADD_MAPPED_SUPERCLASS_TO_XML) {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				final OrmResourceModelProvider modelProvider;
				if (model.isMappingXMLDefault()) {
					modelProvider = OrmResourceModelProvider.getDefaultModelProvider(project);
				}
				else {
					modelProvider = OrmResourceModelProvider.getModelProvider(project, model.getMappingXMLName());
				}
				modelProvider.modify(new Runnable() {
					public void run() {
						OrmResource resource = modelProvider.getResource();
						XmlEntityMappings entityMappings = resource.getEntityMappings();
						if (entityMappings == null) {
							entityMappings = OrmFactory.eINSTANCE.createXmlEntityMappings();
							entityMappings.setVersion(VERSION_STRING);
						}
	
						XmlMappedSuperclass xmlMappedSuperclass = OrmFactory.eINSTANCE.createXmlMappedSuperclass();
						xmlMappedSuperclass.setClassName(model.getQualifiedJavaClassName());
						
						if (model.isCompositePK()) {
							XmlIdClass idClass = OrmFactory.eINSTANCE.createXmlIdClass();
							idClass.setClassName(model.getIdClassName());
							xmlMappedSuperclass.setIdClass(idClass);
						}
						
						List<String> pkFields = model.getPKFields();
						if (pkFields.size() > 0) {
							Attributes entityAttributes = OrmFactory.eINSTANCE.createAttributes();
							List<XmlIdImpl> ids = new ArrayList<XmlIdImpl>();
							for (String fieldName : pkFields) {
								XmlIdImpl idImpl = OrmFactory.eINSTANCE.createXmlIdImpl();
								idImpl.setName(fieldName);
								ids.add(idImpl);
							}
							entityAttributes.eSet(OrmPackage.ATTRIBUTES__IDS, ids);
							xmlMappedSuperclass.setAttributes(entityAttributes);
						}
	
						String accessTypeString = FIELD;
						if (!model.isFieldAccess()) {
							accessTypeString = PROPERTY;
						}
						AccessType accessType = OrmFactory.eINSTANCE.createAccessTypeFromString(null, accessTypeString);
						xmlMappedSuperclass.setAccess(accessType);
						entityMappings.getMappedSuperclasses().add(xmlMappedSuperclass);
						
						resource.getContents().add(entityMappings);
					}
				});
				return Status.OK_STATUS;
			}
		};
		return job;		
	}
	
	/**
	 * Register alternative mapping XML and/or classes in the persistence.xml
	 * 
	 * @param model entity data model
	 * @param project JPA project in which the entity will be created
	 * @return the created job
	 */
	private Job registerMappingXML(final CreateEntityTemplateModel model, final IProject project) {
		Job job = new Job(EntityWizardMsg.APPLY_CHANGES_TO_PERSISTENCE_XML) {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				final PersistenceResourceModelProvider pmp = 
					PersistenceResourceModelProvider.getDefaultModelProvider(project);
				pmp.modify(new Runnable() {
						public void run() {
							String fileName = getLastSegment(model.getMappingXMLName());
							PersistenceResource persistenceResource = pmp.getResource();
							XmlPersistence xmlPersistence = persistenceResource.getPersistence();
							EList<XmlPersistenceUnit> persistenceUnits = xmlPersistence.getPersistenceUnits();
							XmlPersistenceUnit persistenceUnit = persistenceUnits.get(0);// Multiply persistence unit support
							if (!model.isMappingXMLDefault()) {
								boolean newXmlMappingFile = true;
								EList<XmlMappingFileRef> xmlMappingFiles = persistenceUnit.getMappingFiles();
								for (XmlMappingFileRef fileRef : xmlMappingFiles) {
									if (fileName.equals(fileRef.getFileName())) {
										newXmlMappingFile = false;
										break;
									}
								}						
								if (newXmlMappingFile) {
									XmlMappingFileRef xmlMappingFileRef = PersistenceFactory.eINSTANCE.createXmlMappingFileRef();
									xmlMappingFileRef.setFileName(fileName);
									persistenceUnit.getMappingFiles().add(xmlMappingFileRef);
								}
							}
							if (!model.isNonEntitySuperclass() && !JptCorePlugin.discoverAnnotatedClasses(project)) {
								XmlJavaClassRef classRef = PersistenceFactory.eINSTANCE.createXmlJavaClassRef();
								classRef.setJavaClass(model.getQualifiedJavaClassName());
								persistenceUnit.getClasses().add(classRef);
							}
							persistenceResource.getContents().add(xmlPersistence);
						}
					});
				
				return Status.OK_STATUS;
			}
		};
		return job;

	}
	
	/**
	 * @param input the name of mapping XML from the class wizard page. It is relative path from the source folder
	 * and includes META-INF folder
	 * @return the simple name of the mapping XML
	 */
	private String getLastSegment(String input) {
		String output = input;
		if (input.indexOf(SEPARATOR) != -1) {
			output = input.substring(input.lastIndexOf(SEPARATOR) + 1);
		}
		return output;
	}
	
}
