Skip to main content
summaryrefslogblamecommitdiffstats
blob: 37111f07c9dba86f2b68ae6edfcb5c1cd5455682 (plain) (tree)
1
2
3
4
5
6
7
8
                                                                                
                                                        





                                                                                
















                                                                                 

                                           
                                                     

                                                      
                                         
                                       
                                     

                                                   
                                                                  
                                                                     
                                                                 
                                                             
                                                       
                                          
                                                        
                                                     






                                                                                                 





                                                                            


               
   
                                                 
                                                                                                                     




                                   


                                           


                                                                                
                                                                                                                                                                           



                                                        

                                                                                



                                                                                                                     

                                  
                                                                                                            


                                                          
                                               

         
                                                        
                                       
                



                                                                                                    
                                             
                                                                                                                                 
                                                                                                    










                                                                                    
                                                
                                            




                                                                                                                                                  
                         

                                                             
                         



                                     








                                                                                                                               
                                                                                                                



                                       
                                                                                                     





                                             
                                                                       




                                                                                                                            
                                             








                                                                                           
           

                                                                                                       
                                                                                                      
           
                                                                                                                         

                                                                        
                                                                   
                                                                        

                         
                                                                                        


                                        
           


                                                                                        
                                                    

                                                                                                          
        



                                                        

                                                        

         
                                                                          
                                                  

                                         
                                                

         
                                                                             
                                                   
                                                  













                                                                               

         





                                                                                     






                                                                                                        
                                                     

                                                                                                                                              



                                             
                                                                           
                                                                 
                                                                                                  
                                                       













                                                                            
                                        

















                                                                                                                 



                                                                                    

                                                                     
                 
                                           
































                                                                                                      
                                                  

         
                                      



                                               
                                      



                                                       
                                      
                                    
                                                                   

         
                                      







                                                                                    
                         







                                                                                                                                                                     
                                                                  
         
                                                                
                
                                                                

                
                                                                        




                                                
                                                                                  













                                                                   
/*******************************************************************************
 * Copyright (c) 2008, 2010 Oracle. 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:
 *     Oracle - initial API and implementation
 *******************************************************************************/
package org.eclipse.jpt.core.resource;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.jem.util.emf.workbench.EMFWorkbenchContextBase;
import org.eclipse.jem.util.emf.workbench.FlexibleProjectResourceSet;
import org.eclipse.jem.util.emf.workbench.IEMFContextContributor;
import org.eclipse.jem.util.emf.workbench.ProjectResourceSet;
import org.eclipse.jpt.common.core.JptCommonCorePlugin;
import org.eclipse.jpt.core.JptCorePlugin;
import org.eclipse.jpt.core.resource.xml.JpaXmlResource;
import org.eclipse.jpt.utility.internal.ListenerList;
import org.eclipse.wst.common.componentcore.internal.impl.WTPResourceFactoryRegistry;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateInputProvider;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidator;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidatorImpl;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidatorPresenter;

/**
 * Provisional API: This interface is part of an interim API that is still
 * under development and expected to change significantly before reaching
 * stability. It is available at this early stage to solicit feedback from
 * pioneering adopters on the understanding that any code that uses this API
 * will almost certainly be broken (repeatedly) as the API evolves.
 * 
 * @version 2.3
 * @since 2.2
 */
public abstract class AbstractXmlResourceProvider
	implements JpaXmlResourceProvider, IEMFContextContributor, ResourceStateInputProvider, ResourceStateValidator
{
	protected IProject project;
	
	protected URI fileUri;
	
	protected JpaXmlResource resource;
	
	protected IContentType contentType;
	
	protected final ResourceAdapter resourceAdapter = new ResourceAdapter();
	
	protected final ListenerList<JpaXmlResourceProviderListener> listenerList = new ListenerList<JpaXmlResourceProviderListener>(JpaXmlResourceProviderListener.class);
	
	protected ResourceStateValidator stateValidator;
	
	
	/**
	 * Create a new AbstractResourceModelProvider for the given project and 
	 * resourcePath.  The resourcePath may be either 
	 * 	a) an absolute workspace-relative platform resource path (e.g. "/MyProject/src/META-INF/foobar.xml") 
	 * 	or b) a relative runtime path (e.g. "META-INF/foobar.xml".)  
	 * In either case, {@link #buildFileUri(IPath)} will attempt to build an absolutely pathed 
	 * URI for the given path.
	 */
	public AbstractXmlResourceProvider(IProject project, IPath resourcePath, IContentType contentType) {
		super();
		this.project = project;
		this.fileUri = buildFileUri(resourcePath);
		this.contentType = contentType;
	}
	
	protected URI buildFileUri(IPath resourcePath) {
		URI resourceUri = null;
		
		if (resourcePath.isAbsolute()) {
			resourceUri = URI.createPlatformResourceURI(resourcePath.toString(), false);
		}
		else {
			IPath absolutePath = 
				JptCommonCorePlugin.getResourceLocator(this.project).getResourcePath(this.project, resourcePath);
			resourceUri = URI.createPlatformResourceURI(absolutePath.toString(), false);
		}
		
		URIConverter uriConverter = getResourceSet().getURIConverter();
		return uriConverter.normalize(resourceUri);
	}
	
	/**
	 * Return the resource, if it exists.  If no file exists for this resource, 
	 * this will return a stub resource.  You must call #createResource() to 
	 * create the file on the file system.
	 */
	public JpaXmlResource getXmlResource() {
		if (this.resource == null) {
			JpaXmlResource newResource = (JpaXmlResource) WorkbenchResourceHelper.getOrCreateResource(this.fileUri, getResourceSet());
			//EMF caches resources based on URI.  If the resource has changed content types (say the schema was changed
			//from orm to eclipselink-orm), then the resource will be of the wrong type and we need to create a new one.
			if (newResource.getContentType().equals(this.contentType)) {
				this.resource = newResource;
			}
			else {
				this.createResourceAndLoad();
			}
		}
		return this.resource;
	}
	
	protected JpaXmlResource createResourceAndLoad() {
		this.resource = createResource();
		this.loadResource();
		return this.resource;
	}
	
	protected JpaXmlResource createResource() {
		Resource.Factory resourceFactory = 
			WTPResourceFactoryRegistry.INSTANCE.getFactory(this.fileUri, this.contentType.getDefaultDescription());
		return (JpaXmlResource) getResourceSet().createResource(this.fileUri, resourceFactory);		
	}
	
	protected void loadResource() {
		try {
			this.resource.load(((ProjectResourceSet) getResourceSet()).getLoadOptions());
		}
		catch (IOException e) {
			JptCorePlugin.log(e);
		}
	}
	
	protected void createResourceAndUnderlyingFile(Object config) {
		this.resource = createResource();
		if (this.resource.fileExists()) { //always possible that the file already exists when the jpa facet is added
			loadResource();
		}
		else {
			populateRoot(config);
			try {
				this.resource.saveIfNecessary(); //this writes out the file
			}
			catch (Exception e) {
				JptCorePlugin.log(e);
			}
		}
	}
	
	/**
	 * This will actually create the underlying file and the JpaXmlResource that corresponds to it.
	 * It also populates the root of the file.
	 * @param config - A configuration object used to specify options for creation of the resource
	 */
	public JpaXmlResource createFileAndResource(final Object config, IProgressMonitor monitor) throws CoreException {
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) {
				createResourceAndUnderlyingFile(config);
			}
		};
		workspace.run(runnable, this.project, IWorkspace.AVOID_UPDATE, monitor);
		return this.resource;	
	}
	
	/**
	 * Used to optionally fill in the root information of a resource if it does not 
	 * exist as a file
	 */
	protected void populateRoot(Object config) {
		//TODO potentially call resource.populateRoot() instead of the resourceProvider doing this
	}
	

	/**
	 * minimize the scope of the suppressed warnings
	 */
	protected EList<EObject> getResourceContents() {
		return this.resource.getContents();
	}

	public void addListener(JpaXmlResourceProviderListener listener) {
		if (this.listenerList.isEmpty()) {
			engageResource();
		}
		this.listenerList.add(listener);
	}
	
	public void removeListener(JpaXmlResourceProviderListener listener) {
		this.listenerList.remove(listener);
		if (this.listenerList.isEmpty()) {
			disengageResource();
		}
	}
	
	private void engageResource() {
		if (this.resource != null) {
			this.resource.eAdapters().add(this.resourceAdapter);
		}
 	}
	
	private void disengageResource() {
		if (this.resource != null) {
			this.resource.eAdapters().remove(this.resourceAdapter);
		}
	}
	
	protected FlexibleProjectResourceSet getResourceSet() {
		return (FlexibleProjectResourceSet) getEmfContext().getResourceSet();
	}
	
	protected EMFWorkbenchContextBase getEmfContext() {
		return WorkbenchResourceHelper.createEMFContext(this.project, this);
	}
	
	public IProject getProject() {
		return this.project;
	}
	
	protected void resourceIsLoadedChanged(Resource aResource, boolean oldValue, boolean newValue) {
		if ( ! this.listenerList.isEmpty()) {
			int eventType= newValue ? JpaXmlResourceProviderEvent.RESOURCE_LOADED : JpaXmlResourceProviderEvent.RESOURCE_UNLOADED;
			JpaXmlResourceProviderEvent evt = new JpaXmlResourceProviderEvent(this, eventType);
			notifyListeners(evt);
		}
	}
	
	protected void notifyListeners(JpaXmlResourceProviderEvent event) {
		NotifyRunner notifier = new NotifyRunner(event); 
		for (JpaXmlResourceProviderListener listener : this.listenerList.getListeners()) {
			notifier.setListener(listener);
			SafeRunner.run(notifier);
		}
	}
	
	public IStatus validateEdit(Object context) {
		IWorkspace work = ResourcesPlugin.getWorkspace();
		IFile file = WorkbenchResourceHelper.getFile(this.resource);
		if (file != null) {
			IFile[] files = { file };
			if (context == null) {
				context = IWorkspace.VALIDATE_PROMPT;
			}
			return work.validateEdit(files, context);
		} 
		return Status.OK_STATUS;
	}
	
	
	// **************** IEMFContextContributor impl ***************************
	
	private boolean contributedToEmfContext = false;
	
	public void primaryContributeToContext(EMFWorkbenchContextBase context) {
		if (! this.contributedToEmfContext) {
			context.getResourceSet().setResourceFactoryRegistry(WTPResourceFactoryRegistry.INSTANCE);
			this.contributedToEmfContext = true;
		}
	}
	
	public void secondaryContributeToContext(EMFWorkbenchContextBase aNature) {
		// no op
	}
	
	
	// **************** ResourceStateValidator impl ****************************
	
	public ResourceStateValidator getStateValidator() {
		if (this.stateValidator == null) {
			this.stateValidator = createStateValidator();
		}
		return this.stateValidator;
	}
	
	private ResourceStateValidator createStateValidator() {
		return new ResourceStateValidatorImpl(this);
	}
	
	public void checkActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		getStateValidator().checkActivation(presenter);	
	}
	
	public void lostActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		getStateValidator().lostActivation(presenter);	
	}
	
	public IStatus validateState(ResourceStateValidatorPresenter presenter) throws CoreException {
		if (presenter == null) {
			return Status.OK_STATUS;
		}
		return getStateValidator().validateState(presenter);
	}
	
	public boolean checkSave(ResourceStateValidatorPresenter presenter) throws CoreException {
		return getStateValidator().checkSave(presenter);
	}
	
	public boolean checkReadOnly() {
		return getStateValidator().checkReadOnly();
	}
	
	
	// **************** ResourceStateInputProvider impl ************************
	
	public boolean isDirty() {	
		return this.resource.isModified();
	}
	
	@SuppressWarnings("unchecked")
	public List getNonResourceFiles() {
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List getNonResourceInconsistentFiles() {
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List getResources() {
		return Collections.singletonList(getXmlResource());
	}
	
	@SuppressWarnings("unchecked")
	public void cacheNonResourceValidateState(List roNonResourceFiles) {
		// do nothing
	}
	
	
	// **************** member classes *****************************************
	
	protected class ResourceAdapter extends AdapterImpl {
		@Override
		public void notifyChanged(Notification notification) {
			if ( notification.getEventType() == Notification.SET && notification.getFeatureID(null) == Resource.RESOURCE__IS_LOADED) {
				resourceIsLoadedChanged((Resource) notification.getNotifier(), notification.getOldBooleanValue(), notification.getNewBooleanValue());
			}
		}
	}
	
	
	public static class NotifyRunner implements ISafeRunnable 
	{
		private final JpaXmlResourceProviderEvent event;
		
		private JpaXmlResourceProviderListener listener;
		
		
		public NotifyRunner(JpaXmlResourceProviderEvent event) {
			Assert.isNotNull(event);
			this.event = event;
		}
		
		
		public void setListener(JpaXmlResourceProviderListener listener) {
			this.listener = listener;
		}
		
		public void run() throws Exception {
			if (listener != null) {
				listener.modelChanged(event);
			}
		}
		
		public void handleException(Throwable exception) { 
			JptCorePlugin.log(exception);
		}
	}
}

Back to the top