Java tutorial
/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Spindle, an Eclipse Plugin for Tapestry. * * The Initial Developer of the Original Code is * Intelligent Works Incorporated. * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * glongman@intelligentworks.com * * ***** END LICENSE BLOCK ***** */ package com.iw.plugins.spindle.editors; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.util.Iterator; import org.eclipse.core.internal.resources.File; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IStorage; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.ui.javaeditor.JarEntryEditorInput; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.text.IDocument; import org.eclipse.pde.core.IEditable; import org.eclipse.pde.core.IModel; import org.eclipse.pde.internal.ui.editor.IPDEEditorPage; import org.eclipse.pde.internal.ui.editor.PDEEditorContributor; import org.eclipse.pde.internal.ui.editor.PDEMultiPageXMLEditor; import org.eclipse.pde.internal.ui.editor.SystemFileEditorInput; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IPartListener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.dialogs.SaveAsDialog; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.views.properties.IPropertySheetPage; import com.iw.plugins.spindle.MessageUtil; import com.iw.plugins.spindle.TapestryPlugin; import com.iw.plugins.spindle.model.BaseTapestryModel; import com.iw.plugins.spindle.model.ITapestryModel; import com.iw.plugins.spindle.model.TapestryApplicationModel; import com.iw.plugins.spindle.model.TapestryComponentModel; import com.iw.plugins.spindle.model.manager.TapestryProjectModelManager; import com.iw.plugins.spindle.project.ITapestryProject; import com.iw.plugins.spindle.util.JarEditorInputWrapper; import com.iw.plugins.spindle.util.SpindleMultiStatus; import com.iw.plugins.spindle.util.SpindleStatus; import com.iw.plugins.spindle.util.Utils; public abstract class SpindleMultipageEditor extends PDEMultiPageXMLEditor { private static String EDITOR_NAME = "SpindleMultipageEditor"; private static String WRONG_EDITOR = EDITOR_NAME + ".wrongEditor"; private static String WRONG_LOCATION = EDITOR_NAME + ".wrongLocation"; private boolean dirty = false; private boolean duringInit = false; private IPropertySheetPage propertySheetPage; public static final String SOURCE_PAGE = "SOURCEPAGE"; /** * Constructor for TapestryMultipageEditor */ public SpindleMultipageEditor() { super(); } public void init(IEditorSite site, IEditorInput input) throws PartInitException { duringInit = true; if (isValidContentType(input) == false) { String message = MessageUtil.getFormattedString(WRONG_EDITOR, input.getName()); IStatus s = new Status(IStatus.ERROR, TapestryPlugin.getDefault().getPluginId(), IStatus.OK, message, null); throw new PartInitException(s); } try { checkValidLocation(input); } catch (CoreException e) { String message = MessageUtil.getFormattedString(WRONG_LOCATION, input.getName()); SpindleMultiStatus status = new SpindleMultiStatus(IStatus.ERROR, message); status.addStatus(e.getStatus()); TapestryPlugin.getDefault().logException(e); throw new PartInitException(status); } if (input instanceof JarEntryEditorInput) { input = (IEditorInput) new JarEditorInputWrapper((JarEntryEditorInput) input); } setSite(site); setInput(input); Object inputObject = null; if (input instanceof SystemFileEditorInput) { inputObject = input.getAdapter(File.class); } else if (input instanceof FileEditorInput) { inputObject = input.getAdapter(IFile.class); } else if (input instanceof JarEditorInputWrapper) { inputObject = input.getAdapter(IFile.class); } site.setSelectionProvider(this); try { initializeModels(inputObject); } catch (CoreException e) { throw new PartInitException(e.getStatus()); } for (Iterator iter = super.getPages(); iter.hasNext();) { IEditorPart part = (IEditorPart) iter.next(); part.init(site, input); } if (inputObject instanceof IFile) { setTitle(((IFile) inputObject).getName()); } else if (inputObject instanceof java.io.File) { setTitle("system:" + ((java.io.File) inputObject).getName()); } else { setTitle(input.toString()); } getSite().getPage().addPartListener(new PartListener(this)); if (dirty) { doSave(new NullProgressMonitor()); } BaseTapestryModel tapModel = (BaseTapestryModel) model; tapModel.setDirty(false); if (!tapModel.isEditable()) { tapModel.setEditable(!tapModel.getUnderlyingStorage().isReadOnly()); } duringInit = false; } public boolean isModelCorrect(Object model) { return ((BaseTapestryModel) model).isLoaded(); } public void doSave(IProgressMonitor monitor) { final IEditorInput input = getEditorInput(); final IDocumentProvider documentProvider = getDocumentProvider(); if (documentProvider == null) return; if (documentProvider.isDeleted(getEditorInput())) { if (isSaveAsAllowed()) { performSaveAs(monitor); } else { Shell shell = getSite().getShell(); MessageDialog.openError(shell, "Error saving", "The underlying resource has been deleted"); } } else { commitFormPages(true); resynchDocument(true); WorkspaceModifyOperation op = new WorkspaceModifyOperation() { public void execute(final IProgressMonitor monitor) throws CoreException { documentProvider.saveDocument(monitor, input, documentProvider.getDocument(input), true); } }; Shell shell = getSite().getWorkbenchWindow().getShell(); try { documentProvider.aboutToChange(input); op.run(monitor); documentProvider.changed(input); dirty = false; firePropertyChange(PROP_DIRTY); PDEEditorContributor contributor = getContributor(); if (contributor != null) contributor.updateActions(); } catch (InterruptedException x) { } catch (InvocationTargetException x) { TapestryPlugin.getDefault().logException(x); } try { BaseTapestryModel tmodel = (BaseTapestryModel) model; tmodel.setDirty(false); tmodel.reload(); if (!tmodel.isLoaded()) { IWorkbenchWindow window = TapestryPlugin.getDefault().getActiveWorkbenchWindow(); IWorkbenchPage page = window.getActivePage(); if (page != null) { try { page.showView(PlatformUI.PLUGIN_ID + ".views.TaskList"); } catch (PartInitException e) { ErrorDialog.openError(window.getShell(), "Could not show the Task View!", //$NON-NLS-1$ e.getMessage(), e.getStatus()); } } } } catch (Exception e) { } dirty = false; } // TapestrySourcePage sourcePage = (TapestrySourcePage)getPage(SOURCE_PAGE); // sourcePage.checkProblemMarkers(); } /** * update the model with any changes to the source page. * i.e. grab the source page's text and reparse. * @see PDEMultiPageEditor#updateModel() */ protected boolean updateModel() { BaseTapestryModel model = (BaseTapestryModel) getModel(); IDocument document = getDocumentProvider().getDocument(getEditorInput()); String text = document.get(); boolean cleanModel = false; try { InputStream stream = new ByteArrayInputStream(text.getBytes("UTF8")); model.reload(stream); cleanModel = model.isLoaded(); try { stream.close(); } catch (IOException e) { } } catch (Exception e) { TapestryPlugin.getDefault().logException(e); } return cleanModel; } protected void resynchDocument(boolean onSave) { // flush the model content into // the document so that the source editor will // pick up the changes. BaseTapestryModel tmodel = (BaseTapestryModel) model; if (!tmodel.isEditable()) { return; } if (!(tmodel.isDirty() || !tmodel.isInSync())) { return; } try { // need to update the document IDocument document = getDocumentProvider().getDocument(getEditorInput()); document.set(flushModelIntoString(tmodel)); if (!onSave) { fireSaveNeeded(); } } catch (IOException e) { TapestryPlugin.getDefault().logException(e); } } protected String flushModelIntoString(IEditable editableModel) throws IOException { StringWriter swriter = new StringWriter(); PrintWriter writer = new PrintWriter(swriter); editableModel.save(writer); writer.flush(); swriter.close(); return swriter.toString(); } /** * @see PDEMultiPageEditor#isModelDirty(Object) */ protected boolean isModelDirty(Object model) { return model != null && model instanceof IEditable && model instanceof IModel && ((IModel) model).isEditable() && ((IEditable) model).isDirty(); } protected boolean isValidContentType(IEditorInput input) { if (input instanceof JarEntryEditorInput) { input = (IEditorInput) new JarEditorInputWrapper((JarEntryEditorInput) input); } IFile file = (IFile) input.getAdapter(IFile.class); String name = file.getName().toLowerCase(); String valid = getValidExtension(); return name.endsWith(valid); } protected void checkValidLocation(IEditorInput input) throws CoreException { if (input instanceof JarEntryEditorInput) { return; } IFile file = (IFile) input.getAdapter(IFile.class); SpindleStatus status = new SpindleStatus(); if (file == null) { status.setError("Could not open editor...could not adapt the editor input into a file"); throw new CoreException(status); } String filePath = file.getFullPath().toString(); ITapestryProject project = TapestryPlugin.getDefault().getTapestryProjectFor(file); if (project == null) { status.setError("Could not open editor.. " + filePath + " is not in a Tapestry Project"); throw new CoreException(status); } IJavaProject jproject = TapestryPlugin.getDefault().getJavaProjectFor(file); if (jproject == null) { status.setError("Could not open editor..could not find the Java Project nature for " + filePath); throw new CoreException(status); } IFolder parentFolder = (IFolder) file.getParent(); IJavaElement element = JavaCore.create(parentFolder); if (element == null || !element.exists()) { status.setError( "Could not open editor..could not locate " + file.getName() + " in the project src path"); throw new CoreException(status); } } protected abstract String getValidExtension(); /** * @see PDEMultiPageEditor#createModel(Object) */ protected Object createModel(Object input) throws CoreException { if (input instanceof IFile) { return createResourceModel((IFile) input); } return null; } protected ITapestryModel createResourceModel(IStorage storage) throws CoreException { InputStream stream = null; ITapestryProject tproject = null; TapestryProjectModelManager modelProvider = null; try { tproject = TapestryPlugin.getDefault().getTapestryProjectFor(storage); if (tproject != null) { modelProvider = tproject.getModelManager(); } } catch (CoreException e) { SpindleMultiStatus multiStatus = new SpindleMultiStatus(); multiStatus.setError("Could not open"); multiStatus.addStatus(e.getStatus()); Shell shell = TapestryPlugin.getDefault().getActiveWorkbenchShell(); if (shell == null) { shell = new Shell(); } throw new CoreException(multiStatus); } modelProvider.connect(storage, this); BaseTapestryModel model = (BaseTapestryModel) modelProvider.getEditableModel(storage, this); if (!model.isInSync() || model.isDirty()) { Utils.saveModel(model, new NullProgressMonitor()); } try { stream = storage.getContents(); } catch (Exception e) { TapestryPlugin.getDefault().logException(e); return null; } // try { // model.load(stream); // } catch (CoreException e) { // e.printStackTrace(); // TapestryPlugin.getDefault().logException(e); // } try { stream.close(); } catch (IOException e) { TapestryPlugin.getDefault().logException(e); } dirty = false; return model; } public void updateTitle(String value) { setTitle(value); } public void updateTitle() { firePropertyChange(IWorkbenchPart.PROP_TITLE); } public boolean isSaveAsAllowed() { ITapestryModel model = (ITapestryModel) getModel(); return !model.getUnderlyingStorage().isReadOnly(); } /** * @see EditorPart#doSaveAs() */ public void doSaveAs() { performSaveAs(null); } protected void performSaveAs(IProgressMonitor monitor) { Shell shell = getSite().getShell(); SaveAsDialog dialog = new SaveAsDialog(shell); if (dialog.open() == Dialog.CANCEL) { if (monitor != null) monitor.setCanceled(true); return; } IPath filePath = dialog.getResult(); if (filePath == null) { if (monitor != null) monitor.setCanceled(true); return; } filePath = makeValidSaveAsPath(filePath); filePath = filePath.removeTrailingSeparator(); final String fileName = filePath.lastSegment(); IPath folderPath = filePath.removeLastSegments(1); if (folderPath == null) { if (monitor != null) monitor.setCanceled(true); return; } IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IFile file = root.getFile(filePath); final FileEditorInput newInput = new FileEditorInput(file); WorkspaceModifyOperation op = new WorkspaceModifyOperation() { public void execute(final IProgressMonitor monitor) throws CoreException { getDocumentProvider().saveDocument(monitor, newInput, getDocumentProvider().getDocument(getEditorInput()), true); } }; boolean success = false; try { commitFormPages(true); resynchDocument(true); new ProgressMonitorDialog(shell).run(false, true, op); success = true; } catch (InterruptedException x) { } catch (InvocationTargetException x) { Throwable t = x.getTargetException(); TapestryPlugin.getDefault().logException(t); } finally { if (monitor != null) monitor.setCanceled(!success); } } protected IPath makeValidSaveAsPath(IPath candidate) { String extension = candidate.getFileExtension(); IPath allButExtension = candidate.removeFileExtension(); if (model instanceof TapestryApplicationModel) { if ("application".equals(extension)) { return candidate; } else if (extension == null) { return allButExtension.addFileExtension("application"); } } else if (model instanceof TapestryComponentModel) { if ("jwc".equals(extension)) { return candidate; } else if (extension == null) { return allButExtension.addFileExtension("jwc"); } } return null; } protected class PartListener implements IPartListener { private SpindleMultipageEditor editor; /** * Constructor for PartListener */ public PartListener(SpindleMultipageEditor editor) { super(); this.editor = editor; } private void synchExternalChanges(IWorkbenchPart part) { BaseTapestryModel bmodel = (BaseTapestryModel) model; if (part == editor && !bmodel.isInSync()) { resynchDocument(false); showPage(SOURCE_PAGE); bmodel.setOutOfSynch(false); } } /** * @see IPartListener#partActivated(IWorkbenchPart) */ public void partActivated(IWorkbenchPart part) { synchExternalChanges(part); } /** * @see IPartListener#partBroughtToTop(IWorkbenchPart) */ public void partBroughtToTop(IWorkbenchPart part) { synchExternalChanges(part); } /** * @see IPartListener#partClosed(IWorkbenchPart) */ public void partClosed(IWorkbenchPart part) { } /** * @see IPartListener#partDeactivated(IWorkbenchPart) */ public void partDeactivated(IWorkbenchPart part) { } /** * @see IPartListener#partOpened(IWorkbenchPart) */ public void partOpened(IWorkbenchPart part) { } } /** * @see PDEMultiPageEditor#fireSaveNeeded() */ public void fireSaveNeeded() { if (!duringInit) { dirty = true; super.fireSaveNeeded(); } } /** * @see PDEMultiPageEditor#isDirty() */ public boolean isDirty() { return dirty; } /** * @see org.eclipse.pde.internal.ui.editor.PDEMultiPageEditor#createPages() */ protected void createPages() { addPage(SpindleMultipageEditor.SOURCE_PAGE, new XMLEditorPage(this)); } /** * @see org.eclipse.ui.IWorkbenchPart#dispose() */ public void dispose() { super.dispose(); ITapestryModel model = (ITapestryModel) getModel(); try { if (model != null) { IStorage storage = model.getUnderlyingStorage(); TapestryPlugin.getTapestryModelManager(storage).disconnect(storage, this); } } catch (CoreException e) { } } /** * @see org.eclipse.pde.internal.ui.editor.PDEMultiPageEditor#getHomePage() */ public IPDEEditorPage getHomePage() { return null; } /** * @see org.eclipse.pde.internal.ui.editor.PDEMultiPageEditor#getSourcePageId() */ protected String getSourcePageId() { return null; } /** * Method getDefaultHeadingImage. * @return Image */ public abstract Image getDefaultHeadingImage(); }