blob: 9da0e70bd9300ee1dd616d92a6e1973bddfd64fc [file] [log] [blame]
/***************************************************************************************************
* Copyright (c) 2003, 2004 IBM Corporation and others. 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: IBM Corporation - initial API and implementation
**************************************************************************************************/
package org.eclipse.jst.j2ee.internal.webservice.editmodel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EventObject;
import java.util.Hashtable;
import java.util.List;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jst.j2ee.internal.webservice.plugin.WebServicePlugin;
import org.eclipse.wst.common.internal.emf.resource.ReferencedResource;
public abstract class CompositeEditModel extends EditModel implements CommandStackListener {
protected int fReferenceCount;
protected Hashtable fEditModels;
protected Hashtable fResources;
protected Hashtable fRootObjects;
protected List fDescriptors;
protected EditModelEvent dirtyModelEvent;
private List fListeners;
protected boolean isNotifing = false;
public int getReferenceCount() {
return fReferenceCount;
}
public boolean access() {
fReferenceCount++;
if (fReferenceCount == 1) {
//get all the registered edit models
IConfigurationElement[] elements = getExtensions();
//get a command stack
createCommandStack();
for (int i = 0; i < elements.length; i++) {
try {
Object editModelObject = elements[i].createExecutableExtension("class"); //$NON-NLS-1$
if (editModelObject instanceof EditModel) {
//Setup the edit model and add it to the Hashtable
EditModel editModel = (EditModel) editModelObject;
String descriptorName = elements[i].getAttribute("descriptorName"); //$NON-NLS-1$
editModel.setResourceSet(fResourceSet);
editModel.setProject(fProject);
editModel.setInputFile(fInputFile);
editModel.setCommandStack(fCommandStack);
editModel.setParent(this);
fEditModels.put(descriptorName, editModel);
//Get the resource from the editmodel and add it to the resource Hashtable
Resource res = editModel.getModelResource(descriptorName);
if (res == null) {
//Exit access()
return false;
}
//The webservices.xml and webservicesclient.xml do not load as
// ReferencedResources
//so, for the time being, we only do proper accessing on the xmi resources
// we load.
if (res instanceof ReferencedResource)
((ReferencedResource) res).accessForWrite();
//todo: process the resource upon load (i.e. accessForWrite(), etc)
fResources.put(descriptorName, res);
//Get the root object from the resource and add it to the Hashtable
EObject rootObject = editModel.getRootModelObject(descriptorName);
fRootObjects.put(descriptorName, rootObject);
fDescriptors.add(descriptorName);
}
} catch (CoreException e) {
return false;
}
}
}
return true;
}
public abstract IConfigurationElement[] getExtensions();
public void release() {
fReferenceCount--;
if (fReferenceCount == 0) {
//release resources and dispose the edit model.
Resource resource;
int listsize = fDescriptors.size();
for (int i = 0; i < listsize; i++) {
String descriptorName = (String) fDescriptors.get(i);
//release the resource
resource = getModelResource(descriptorName);
//The webservices.xml and webservicesclient.xml do not load as ReferencedResources
//so, for the time being, we only do proper accessing on the xmi resources we load.
if (resource instanceof ReferencedResource)
((ReferencedResource) resource).releaseFromWrite();
else {
//this is a really bad but until we load ReferencedResources for
// webservices.xml and
//webservicesclient.xml we need to explicitly unload
//resource.unload();
}
//remove stored resources, root objects and edit models from Hashtables
fResources.remove(descriptorName);
fRootObjects.remove(descriptorName);
fEditModels.remove(descriptorName);
}
fDescriptors = null;
fCommandStack = null;
dirtyModelEvent = null;
dispose();
}
}
protected abstract void dispose();
/** *************Getting resources and objects ******************* */
public EditModel getEditModel(String descriptorName) {
EditModel em = (EditModel) fEditModels.get(descriptorName);
return em;
}
public Resource getModelResource(String descriptorName) {
Resource res = (Resource) fResources.get(descriptorName);
return res;
}
public EObject getRootModelObject(String descriptorName) {
EObject res = (EObject) fRootObjects.get(descriptorName);
return res;
}
public abstract EObject getRootModelObject();
public abstract Resource getRootModelResource();
/** *********Command Stack related methods*************************** */
public BasicCommandStack createCommandStack() {
if (fCommandStack == null) {
fCommandStack = new BasicCommandStack();
fCommandStack.addCommandStackListener(this);
}
return fCommandStack;
}
public void commandStackChanged(EventObject event) {
if (dirtyModelEvent == null)
dirtyModelEvent = new EditModelEvent(EditModelEvent.DIRTY, this);
if (hasListeners())
notifyListeners(dirtyModelEvent);
}
protected List getListeners() {
if (fListeners == null)
fListeners = new ArrayList();
return fListeners;
}
/**
* Add
*
* @aListener to the list of listeners.
*/
public void addListener(EditModelListener aListener) {
if (aListener != null && !getListeners().contains(aListener))
getListeners().add(aListener);
}
/**
* Returns true if there are any listeners
*/
public boolean hasListeners() {
return !getListeners().isEmpty();
}
/**
* Notify listeners of
*
* @anEvent.
*/
protected void notifyListeners(EditModelEvent anEvent) {
if (fListeners == null)
return;
synchronized (this) {
isNotifing = true;
}
try {
List list = getListeners();
for (int i = 0; i < list.size(); i++)
((EditModelListener) list.get(i)).editModelChanged(anEvent);
} finally {
synchronized (this) {
isNotifing = false;
}
}
}
/** *********Save related methods*************************** */
public final void save(IProgressMonitor monitor) {
//getSaveHandler().access();
try {
IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
public void run(IProgressMonitor aMonitor) {
primSave(aMonitor);
}
};
runSaveOperation(runnable, monitor);
} catch (CoreException ex) {
//Pop up a dialog indicating that problems occurred during the save
MessageDialog.openError(null, WebServicePlugin.getMessage("%TITLE_SAVE_ERROR"), WebServicePlugin.getMessage("%MSG_SAVE_ERROR")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
private void runSaveOperation(IWorkspaceRunnable runnable, IProgressMonitor monitor) throws CoreException {
ResourcesPlugin.getWorkspace().run(runnable, monitor);
}
/**
* This will force all of the referenced Resources to be saved.
*/
public void primSave(IProgressMonitor monitor) {
Resource resource;
int listsize = fDescriptors.size();
for (int i = 0; i < listsize; i++) {
String descriptorName = (String) fDescriptors.get(i);
resource = getModelResource(descriptorName);
if (resource.isModified()) {
try {
resource.save(Collections.EMPTY_MAP);
resource.setModified(false);
} catch (Exception e) {
//Ignore
}
}
}
getCommandStack().saveIsDone();
if (hasListeners()) {
EditModelEvent event = new EditModelEvent(EditModelEvent.SAVE, this);
notifyListeners(event);
}
}
public boolean isDirty() {
Resource resource;
int listsize = fDescriptors.size();
for (int i = 0; i < listsize; i++) {
String descriptorName = (String) fDescriptors.get(i);
resource = getModelResource(descriptorName);
if (resource.isModified()) {
return true;
}
}
return false;
}
public void resourceChanged(EditModelEvent anEvent) {
if (hasListeners()) {
anEvent.setEditModel(this);
notifyListeners(anEvent);
}
}
protected void resourceIsLoadedChanged(Resource aResource, boolean oldValue, boolean newValue) {
//Do nothing for now
}
protected class ResourceAdapter extends AdapterImpl {
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());
}
}
}
}