blob: fb9c6b6b85f2bcd8d969f41f02aa214bd33e3dcc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2005 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.wst.sse.core.internal.provisional.model;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.exceptions.ResourceAlreadyExists;
import org.eclipse.wst.sse.core.internal.provisional.exceptions.ResourceInUse;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
/**
* Responsible for managing IStructuredModels.
*
* This allows clients to share models, so they do not have to be re-created
* or passed around from one client to another. Clients should internally
* enforce that models are gotten and released from locations close to each
* other to prevent model leaks.
*
* There are three ways to get a model based on usage and responsibility: for
* 'MODIFY', just for 'SHARED', and 'UNSHARED'. Contrary to their names, a
* model can technically be modified, and all modifications directly affect
* the commonly shared version of the model. It is part of the API contract,
* however, that clients who get a model for SHARED do not modify it. The
* significance of the 'MODIFY' model is that the client is registering their
* interest in saving changes to the model.
*
* Clients can reference this interface, but should not implement.
*
* @see org.eclipse.wst.sse.core.StructuredModelManager
* @plannedfor 1.0
*/
public interface IModelManagerProposed {
/**
* AccessType is used internally as a JRE 1.4 compatible enumerated type.
* Not intended to be referenced by clients.
*/
static class AccessType {
private String fType;
/**
* default access contructor we use to create our specific constants.
*
* @param type
*/
AccessType(String type) {
super();
fType = type;
}
/**
* For debug purposes only.
*/
public String toString() {
return "Model Access Type: " + fType; //$NON-NLS-1$
}
}
/**
* Constant to provide compile time safe parameter. <code>NOTSHARED</code>signifies
* the client intentially wants a model that is not shared with other
* clients. NOTSHARED models can not be saved.
*/
final AccessType NOTSHARED = new AccessType("NOTSHARED"); //$NON-NLS-1$
/**
* Constant to provide compile-time safe parameter. <code>SHARED</code>signifies
* the client is not intending to make changes and does not care whether
* the model accessed is saved.
*/
final AccessType SHARED = new AccessType("SHARED"); //$NON-NLS-1$
/**
* Constant to provide compile-time safe parameter. <code>MODIFY</code>signifies
* the client is intending to make changes and is responsible for saving
* changes (or not) if they are the last one holding MODIFY access to the
* model before it's released.
*/
final AccessType MODIFY = new AccessType("MODIFY"); //$NON-NLS-1$
/**
* copyModel is similar to a deep clone. The resulting model is shared,
* according to the value of ReadEditType. If a model already is being
* managed for 'newLocation' then a ResourceInUse exception is thrown,
* unless the ReadEditType is NOTSHARED, in which case the resulting model
* can not be saved.
*
* @param oldLocation
* @param newLocation
* @param type
* @return
* @throws ResourceInUse
*
* ISSUE: is this important enough to be API, or can clients solve
* themselves
*/
IStructuredModel copyModel(IPath oldLocation, IPath newLocation, AccessType type) throws ResourceInUse;
/**
* createNewInstance is similar to clone, except the new instance has no
* text content. Note: this produces an UNSHARED model, for temporary use,
* that has the same characteristics as original model. If a true shared
* model is desired, use "copy".
*
* ISSUE: still needed?
*
* @param requester
* @param model
* @return
* @throws IOException
*/
public IStructuredModel createNewInstance(Object requester, IStructuredModel model) throws IOException;
/**
* Factory method, since a proper IStructuredDocument must have a proper
* parser assigned. Note: its assume that IPath does not actually exist as
* a resource yet. If it does, ResourceAlreadyExists exception is thrown.
* If the resource does already exist, then createStructuredDocumentFor is
* the right API to use.
*
* ISSUE: do we want to support this via model manager, or else where?
* ISSUE: do we need two of these? What's legacy use case?
*
* @param location
* @param progressMonitor
* @return
* @throws ResourceAlreadyExists
* @throws IOException
* @throws CoreException
*/
IStructuredDocument createNewStructuredDocumentFor(IPath location, IProgressMonitor progressMonitor) throws ResourceAlreadyExists, IOException, CoreException;
/**
* Factory method, since a proper IStructuredDocument must have a proper
* parser assigned. Note: clients should verify that the resource
* identified by the IPath exists before using this method. If this IFile
* does not exist, then createNewStructuredDocument is the correct API to
* use.
*
* ISSUE: do we want to support this via model manager, or else where?
* ISSUE: do we need two of these? What's legacy use case?
*
* @param location
* @param progressMonitor
* @return
* @throws IOException
* @throws CoreException
*/
IStructuredDocument createStructuredDocumentFor(IPath location, IProgressMonitor progressMonitor) throws IOException, CoreException;
/**
* Note: callers of this method must still release the model when
* finished. Returns the model for this document if it already exists and
* is being shared. Returns null if this is not the case. The ReadEditType
* must be either MODIFY or SHARED.
*
* ISSUE: should we accept IDocument on parameter for future evolution,
* and constrain to StructuredDocuments at runtime?
*
* @param requester
* @param type
* @param document
* @return
*/
IStructuredModel getExistingModel(Object requester, AccessType type, IDocument document);
/**
* Callers of this method must still release the model when finished.
* Returns the model for this location if it already exists and is being
* shared. Returns null if this is not the case. The ReadEditType must be
* either MODIFY or SHARED.
*
* @param requester
* @param type
* @param location
* @return
*/
public IStructuredModel getExistingModel(Object requester, AccessType type, IPath location);
/**
* Returns the model that has the specified document as its structured
* document.
*
* @param requester
* @param type
* @param progressMonitor
* @param document
* @return
*/
public IStructuredModel getModel(Object requester, AccessType type, IProgressMonitor progressMonitor, IDocument document);
/**
* Returns the model based on the content at the specified location.
*
* Note: if the ModelManager does not know how to create a model for
* such a file for content, null is return.
* ISSUE: should we throw some special, meaningful, checked
* exception instead?
*
* @param requester
* @param type
* @param progressMonitor
* @param location
* @return
* @throws IOException
* @throws CoreException
*/
public IStructuredModel getModel(Object requester, AccessType type, IProgressMonitor progressMonitor, IPath location) throws IOException, CoreException;
/**
* This method will not create a new model if it already exists ... if
* force is false. The idea is that a client should call this method once
* with force set to false. If the exception is thrown, then prompt client
* if they want to overwrite.
*
* @param requester
* @param location
* @param force
* @param type
* @param progressMonitor
* @return
* @throws ResourceAlreadyExists
* @throws ResourceInUse
* @throws IOException
* @throws CoreException
*/
IStructuredModel getNewModel(Object requester, IPath location, boolean force, AccessType type, IProgressMonitor progressMonitor) throws ResourceAlreadyExists, ResourceInUse, IOException, CoreException;
/**
* This function returns true if there are other references to the
* underlying model.
*
* @param location
* @return
*/
boolean isShared(IPath location);
/**
* This function returns true if there are other references to the
* underlying model, shared in the specified way. The ReadEditType must be
* either MODIFY or SHARED.
*
* @param location
* @param type
* @return
*/
boolean isShared(IPath location, AccessType type);
/**
* This method can be called when the content type of a model changes. Its
* assumed the contentType has already been changed, and this method uses
* the text of the old one, to repopulate the text of the new one.
*
* @param model
* @return
* @throws IOException
*/
IStructuredModel reinitialize(IStructuredModel model) throws IOException;
/**
* This is used by clients to signify that they are finished with a model
* and will no longer access it or any of its underlying data (such as its
* structured document). The ReadEditType must match what ever the client
* used in the corresponding 'get' method.
*
* This method must be called for every 'get'. Clients should use the
* try/finally pattern to ensure the release is called even if there is an
* unexpected exception.
*
* @param requester
* @param structuredModel
* @param type
*/
void releaseModel(Object requester, IStructuredModel structuredModel, AccessType type);
/**
* Writes the underlying document to the IPath.
*
* ISSUE: we want to just "dump" contents to location, but need to spec.
* all the different cases of shared, etc.
*
* ?If to same location as 'get', then same instance of model, If to
* different location (esp. if shared) then need to leave old instance of
* model, create new model, and save to new location. ?
*
* Cases: IPath is null, write to IPath created with IPath specificed and
* equals IPath created with, write to IPath IPath specified and not
* equals IPath created with, dumps to new IPath, no change in current
* model state.
*
* ISSUE: think through 'normalization' cases
*
*
* @param structuredModel
* @param location - already normalized?
* @param progressMonitor
* @throws UnsupportedEncodingException
* @throws IOException
* @throws CoreException
*
* ISSUE: resource aleady exists? veto override
*/
void saveModel(IStructuredModel structuredModel, IPath location, IProgressMonitor progressMonitor) throws UnsupportedEncodingException, IOException, CoreException;
/**
* Writes the underlying document to the IPath if the model is only shared
* for EDIT by one client. This is the recommended way for 'background
* jobs' to save models, in case the model is being shared by an editor,
* or other client that might desire user intervention to save a resource.
*
* @param structuredModel
* @param location - already normalized?
* @param progressMonitor
* @throws UnsupportedEncodingException
* @throws IOException
* @throws CoreException
*
* ISSUE: is locaiton needed in this case, or just use the one it was
* created with
*/
void saveModelIfNotShared(IStructuredModel structuredModel, IPath location, IProgressMonitor progressMonitor) throws UnsupportedEncodingException, IOException, CoreException;
}