blob: b84da02f3077002852613b74bd3fa56a1589d286 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2012 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.jpa.ui.internal.editors;
import java.util.ListIterator;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jpt.common.core.JptResourceType;
import org.eclipse.jpt.common.ui.WidgetFactory;
import org.eclipse.jpt.common.ui.internal.widgets.FormWidgetFactory;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.model.value.ListAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.ListPropertyValueModelAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.PropertyAspectAdapter;
import org.eclipse.jpt.common.utility.internal.model.value.SimplePropertyValueModel;
import org.eclipse.jpt.common.utility.internal.model.value.TransformationPropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.ListValueModel;
import org.eclipse.jpt.common.utility.model.value.ModifiablePropertyValueModel;
import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.context.JpaRootContextNode;
import org.eclipse.jpt.jpa.core.context.persistence.Persistence;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceXml;
import org.eclipse.jpt.jpa.ui.JpaPlatformUi;
import org.eclipse.jpt.jpa.ui.PersistenceXmlResourceUiDefinition;
import org.eclipse.jpt.jpa.ui.details.JpaPageComposite;
import org.eclipse.jpt.jpa.ui.internal.persistence.JptUiPersistenceMessages;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
/**
* This is the editor for the JPA Persistence Configuration (persistence.xml).
* The pages shown before the XML source editor are retrieved from the
* <code>JpaUiFactory</code>.
*
* @version 2.3
* @since 2.0
*/
@SuppressWarnings("nls")
public class PersistenceEditor
extends FormEditor
{
/**
* The XML text editor.
*/
private StructuredTextEditor editor;
/**
* The root of the holders used to retrieve the persistence unit and be
* notified when it changes.
*/
private ModifiablePropertyValueModel<IFileEditorInput> editorInputHolder;
/**
* The factory used to create the various widgets.
*/
private WidgetFactory widgetFactory;
final ResourceManager resourceManager;
/**
* Creates a new <code>PersistenceEditor</code>.
*/
public PersistenceEditor() {
super();
this.resourceManager = new LocalResourceManager(JFaceResources.getResources());
initialize();
}
/**
* Delegate to the {@link #editor} if necessary.
*/
@Override
public Object getAdapter(@SuppressWarnings("rawtypes") Class adapterClass) {
Object adapter = super.getAdapter(adapterClass);
return (adapter != null) ? adapter : this.editor.getAdapter(adapterClass);
}
@Override
protected void addPages() {
addPersistenceUnitPages();
addXMLEditorPage();
}
/**
* Adds the pages that show the properties of the persistence configuration
* or its persistence units.
*/
private void addPersistenceUnitPages() {
JpaProject jpaProject = getJpaProject();
// The project doesn't have JPA
if (jpaProject == null) {
return;
}
PersistenceXml persistenceXml = jpaProject.getRootContextNode().getPersistenceXml();
if (persistenceXml == null) {
return;
}
JptResourceType resourceType = persistenceXml.getResourceType();
if (resourceType == null) {
return; // might not ever get here... (if we have a p.xml, it probably has a resource type...)
}
JpaPlatformUi jpaPlatformUI = (JpaPlatformUi) jpaProject.getJpaPlatform().getAdapter(JpaPlatformUi.class);
PersistenceXmlResourceUiDefinition definition =
(PersistenceXmlResourceUiDefinition) jpaPlatformUI.getResourceUiDefinition(resourceType);
ListIterator<JpaPageComposite> puPages = definition.buildPersistenceUnitComposites(
buildPersistenceUnitHolder(),
getContainer(),
this.widgetFactory
);
while (puPages.hasNext()) {
JpaPageComposite page = puPages.next();
try {
FormPage formPage = new Page(page);
addPage(formPage);
}
catch (PartInitException e) {
// TODO
}
}
}
/**
* Adds the page containing the XML editor.
*/
private void addXMLEditorPage() {
try {
editor = new StructuredTextEditor();
editor.setEditorPart(this);
int index = addPage(editor, getEditorInput());
setPageText(index, JptUiPersistenceMessages.PersistenceEditor_sourceTab);
}
catch (PartInitException e) {
// TODO
}
}
private ModifiablePropertyValueModel<IFileEditorInput> buildEditorInputHolder() {
return new SimplePropertyValueModel<IFileEditorInput>();
}
private PropertyValueModel<JpaProject> buildJpaProjectHolder() {
return new TransformationPropertyValueModel<IFileEditorInput, JpaProject>(this.editorInputHolder) {
@Override
protected JpaProject transform_(IFileEditorInput fileEditorInput) {
return PersistenceEditor.this.getJpaProject(fileEditorInput.getFile().getProject());
}
};
}
private PropertyValueModel<Persistence> buildPersistenceHolder() {
return new PropertyAspectAdapter<PersistenceXml, Persistence>(buildPersistenceXmlHolder(), PersistenceXml.PERSISTENCE_PROPERTY) {
@Override
protected Persistence buildValue_() {
return subject.getPersistence();
}
};
}
private PropertyValueModel<PersistenceUnit> buildPersistenceUnitHolder() {
return new ListPropertyValueModelAdapter<PersistenceUnit>(buildPersistenceUnitListHolder()) {
@Override
protected PersistenceUnit buildValue() {
return listModel.size() > 0 ? (PersistenceUnit) listModel.get(0) : null;
}
};
}
private ListValueModel<PersistenceUnit> buildPersistenceUnitListHolder() {
return new ListAspectAdapter<Persistence, PersistenceUnit>(buildPersistenceHolder(), Persistence.PERSISTENCE_UNITS_LIST) {
@Override
protected ListIterable<PersistenceUnit> getListIterable() {
return subject.getPersistenceUnits();
}
@Override
protected int size_() {
return subject.getPersistenceUnitsSize();
}
};
}
private PropertyValueModel<PersistenceXml> buildPersistenceXmlHolder() {
return new PropertyAspectAdapter<JpaRootContextNode, PersistenceXml>(buildRootContextNodeHolder(), JpaRootContextNode.PERSISTENCE_XML_PROPERTY) {
@Override
protected PersistenceXml buildValue_() {
return subject.getPersistenceXml();
}
};
}
private PropertyValueModel<JpaRootContextNode> buildRootContextNodeHolder() {
return new TransformationPropertyValueModel<JpaProject, JpaRootContextNode>(buildJpaProjectHolder()) {
@Override
protected JpaRootContextNode transform_(JpaProject jpaProject) {
return jpaProject.getRootContextNode();
}
};
}
private WidgetFactory buildWidgetFactory() {
return new FormWidgetFactory(
new TabbedPropertySheetWidgetFactory()
);
}
@Override
public void dispose() {
this.editorInputHolder.setValue(null);
this.resourceManager.dispose();
super.dispose();
}
@Override
public void doSave(IProgressMonitor monitor) {
getEditor(getPageCount() - 1).doSave(monitor);
}
@Override
public void doSaveAs() {
// do nothing
}
@Override
public IFileEditorInput getEditorInput() {
return (IFileEditorInput) super.getEditorInput();
}
@Override
public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException {
Assert.isLegal(editorInput instanceof IFileEditorInput, "Invalid Input: Must be IFileEditorInput");
super.init(site, editorInput);
setPartName(editorInput.getName());
editorInputHolder.setValue(getEditorInput());
}
/**
* Initializes this multi-page editor.
*/
private void initialize() {
widgetFactory = buildWidgetFactory();
editorInputHolder = buildEditorInputHolder();
}
@Override
public boolean isSaveAsAllowed() {
return false;
}
/**
* Retrieves the JPA project associated with the project owning the editor
* intput file.
*
* @return The JPA project
*/
protected JpaProject getJpaProject() {
return this.getJpaProject(getEditorInput().getFile().getProject());
}
protected JpaProject getJpaProject(IProject project) {
return (JpaProject) project.getAdapter(JpaProject.class);
}
/**
* This extension over <code>FormPage</code> simply complete the layout by
* using the <code>JpaPageComposite</code>'s control as its form content.
*/
class Page
extends FormPage
{
/**
* The wrapped page that actually contains the widgets to show with this
* form page.
*/
private final JpaPageComposite page;
private ImageDescriptor imageDescriptor;
/**
* Creates a new <code>Page</code>.
*
* @param page The wrapped <code>JpaPageComposite</code>
*/
Page(JpaPageComposite page) {
super(PersistenceEditor.this,
page.getClass().getName(),
page.getPageText());
this.page = page;
}
@Override
protected void createFormContent(IManagedForm managedForm) {
ScrolledForm form = managedForm.getForm();
managedForm.getToolkit().decorateFormHeading(form.getForm());
// Update the text and image
updateForm(form);
// Update the layout
updateBody(form);
// This will finish the initialization of the buttons
updateHelpButton();
form.updateToolBar();
}
@Override
public void dispose() {
this.page.dispose();
if (this.imageDescriptor != null) {
PersistenceEditor.this.resourceManager.destroyImage(this.imageDescriptor);
}
super.dispose();
}
@Override
public void setFocus() {
this.page.getControl().setFocus();
}
/**
* Adds the page's control to this page.
*
* @param form The form containing the composite with which the page's
* control is parented
*/
private void updateBody(ScrolledForm form) {
Composite body = form.getBody();
body.setLayout(new TableWrapLayout());
TableWrapData wrapData = new TableWrapData(
TableWrapData.FILL_GRAB,
TableWrapData.FILL_GRAB
);
this.page.getControl().setLayoutData(wrapData);
this.page.getControl().setParent(body);
}
/**
* Updates the text and image of the form.
*
* @param form The form to have its title bar updated by setting the text
* and image, the image can be <code>null</code>
*/
private void updateForm(ScrolledForm form) {
form.setText(this.page.getPageText());
this.imageDescriptor = this.page.getPageImageDescriptor();
if (this.imageDescriptor != null) {
form.setImage(PersistenceEditor.this.resourceManager.createImage(this.imageDescriptor));
}
}
/**
* Adds a help button to the page's toolbar if a help ID exists.
*/
private void updateHelpButton() {
String helpID = this.page.getHelpID();
if (helpID != null) {
Action helpAction = new HelpAction(helpID);
ScrolledForm form = getManagedForm().getForm();
IToolBarManager manager = form.getToolBarManager();
manager.add(helpAction);
}
}
private class HelpAction
extends Action
{
final String helpID;
HelpAction(String helpID) {
super(JptUiPersistenceMessages.PersistenceEditor_page_help,
JFaceResources.getImageRegistry().getDescriptor(Dialog.DLG_IMG_HELP));
this.helpID = helpID;
}
@Override
public void run() {
BusyIndicator.showWhile(getManagedForm().getForm().getDisplay(), new Runnable() {
public void run() {
PlatformUI.getWorkbench().getHelpSystem().displayHelp(helpID);
}
});
}
}
}
}