blob: 3af53a3703730e72b2834fe58dfbcdaf54ef1607 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.j2ee.persistence.unit;
import java.awt.Container;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.Action;
import javax.swing.JButton;
import org.netbeans.api.db.explorer.JDBCDriver;
import org.netbeans.api.db.explorer.JDBCDriverManager;
import org.netbeans.api.java.classpath.JavaClassPathConstants;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.libraries.Library;
import org.netbeans.api.project.libraries.LibraryManager;
import org.netbeans.core.api.multiview.MultiViewPerspective;
import org.netbeans.core.spi.multiview.MultiViewElement;
import org.netbeans.modules.j2ee.persistence.dd.common.Persistence;
import org.netbeans.modules.j2ee.persistence.dd.common.PersistenceUnit;
import org.netbeans.modules.j2ee.persistence.provider.InvalidPersistenceXmlException;
import org.netbeans.modules.j2ee.persistence.provider.Provider;
import org.netbeans.modules.j2ee.persistence.wizard.Util;
import org.netbeans.modules.j2ee.persistence.wizard.entity.WrapperPanel;
import org.netbeans.modules.j2ee.persistence.wizard.unit.PersistenceUnitWizardDescriptor;
import org.netbeans.modules.j2ee.persistence.wizard.unit.PersistenceUnitWizardPanel;
import org.netbeans.modules.j2ee.persistence.wizard.unit.PersistenceUnitWizardPanelDS;
import org.netbeans.modules.j2ee.persistence.provider.ProviderUtil;
import org.netbeans.modules.j2ee.persistence.wizard.library.PersistenceLibrarySupport;
import org.netbeans.modules.j2ee.persistence.wizard.unit.PersistenceUnitWizardPanelJdbc;
import org.netbeans.modules.xml.multiview.*;
import org.netbeans.modules.xml.multiview.ui.*;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.nodes.*;
import org.netbeans.modules.xml.multiview.Error;
import org.openide.util.HelpCtx;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import org.openide.windows.TopComponent;
/**
* Multiview element for persistence.xml.
*
* @author Martin Adamek
* @author Erno Mononen
*/
@MultiViewElement.Registration(
displayName ="#LBL_Design",// NOI18N
iconBase=PUDataObject.ICON,
persistenceType=TopComponent.PERSISTENCE_NEVER,
preferredID=PUDataObject.PREFERRED_ID_DESIGN,
mimeType=PUDataLoader.REQUIRED_MIME,
position=1300
)
public class PersistenceToolBarMVElement extends ToolBarMultiViewElement implements PropertyChangeListener {
private final ModelListener modelListener = new ModelListener();
private ToolBarDesignEditor comp;
private PersistenceView view;
private PUDataObject puDataObject;
private PersistenceUnitPanelFactory factory;
private Action addAction, removeAction;
private Project project;
private boolean needInit = true;
private RequestProcessor.Task repaintingTask;
/** Creates a new instance of DesignMultiViewElement */
public PersistenceToolBarMVElement(Lookup context) {
super(context.lookup(PUDataObject.class));
this.puDataObject=context.lookup(PUDataObject.class);
this.project = FileOwnerQuery.getOwner(puDataObject.getPrimaryFile());
addAction = new AddAction(NbBundle.getMessage(PersistenceToolBarMVElement.class,"LBL_Add"));
removeAction = new RemoveAction(NbBundle.getMessage(PersistenceToolBarMVElement.class,"LBL_Remove"));
comp = new ToolBarDesignEditor();
factory=new PersistenceUnitPanelFactory(comp,puDataObject);
setVisualEditor(comp);
repaintingTask = RequestProcessor.getDefault().create(new Runnable() {
@Override
public void run() {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
repaintView();
}
});
}
});
}
@Override
public SectionView getSectionView() {
return view;
}
@Override
public void componentOpened() {
super.componentOpened();
dObj.addPropertyChangeListener(this);
if (puDataObject != null && puDataObject.getPersistence() != null) {
puDataObject.getPersistence().addPropertyChangeListener(modelListener);
}
}
@Override
public void componentClosed() {
super.componentClosed();
dObj.removePropertyChangeListener(this);
if (puDataObject != null && puDataObject.getPersistence() != null) {
puDataObject.getPersistence().removePropertyChangeListener(modelListener);
}
}
@Override
public void componentShowing() {
super.componentShowing();
view = new PersistenceView();
if (!puDataObject.viewCanBeDisplayed()) {
view.setRoot(Node.EMPTY);
comp.setContentView(view);
return;
}
view.initialize(puDataObject);
comp.setContentView(view);
Object lastActive = comp.getLastActive();
if (lastActive != null) {
view.openPanel(lastActive);
} else {
// Expand the first node in session factory if there is one
Node childrenNodes[] = view.getPersistenceUnitsNode().getChildren().getNodes();
if (childrenNodes.length > 0) {
view.selectNode(childrenNodes[0]);
if(childrenNodes[0].getChildren().getNodes().length>0){
view.selectNode(childrenNodes[0].getChildren().getNodes()[0]);
}
}
}
view.checkValidity();
}
/**
* Tries to repaint the current view.
*
* @return true if repainting succeeded, false otherwise.
*/
private boolean repaintView(){
view = new PersistenceView();
view.initialize(puDataObject);
comp.setContentView(view);
Object lastActive = comp.getLastActive();
if (lastActive!=null) {
view.openPanel(lastActive);
} else {
Node initialNode = view.getPersistenceUnitsNode();
Children ch = initialNode.getChildren();
if (ch.getNodesCount()>0) {
initialNode = ch.getNodes()[0];
}
view.selectNode(initialNode);
}
view.checkValidity();
return true;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
String name = evt.getPropertyName();
if (PUDataObject.PERSISTENCE_UNIT_ADDED_OR_REMOVED.equals(name)){
repaintingTask.schedule(100);
} else if ((PUDataObject.PROPERTY_DATA_MODIFIED.equals(name)
|| PUDataObject.PROPERTY_DATA_UPDATED.equals(name))
&& !this.equals(puDataObject.getActiveMultiViewElement0())) {
needInit = true;
} else if (PUDataObject.NO_UI_PU_CLASSES_CHANGED.equals(name) && this.equals(puDataObject.getActiveMultiViewElement0())) {
//need to refresh classes view of specific persistence unit
//TODO: review if it can be done easier as it looks quite complex
PersistenceUnit pu = evt.getNewValue() instanceof PersistenceUnit ? (PersistenceUnit) evt.getNewValue() : null;
if(pu != null) {
SectionContainer sc = view.getPersistenceUnitsCont();
SectionContainerNode sn = (SectionContainerNode) sc.getNode();
Children ch=sn.getChildren();
NodeSectionPanel nsp;
Node mainPUNode = null;
for(Node n:ch.getNodes()) {
PersistenceUnitNode pun = (PersistenceUnitNode) n;
String pusecname = pun.getDisplayName();
if(pusecname.equals(pu.getName()))
{
mainPUNode = pun.getChildren().getNodes()[0];
break;
}
}
if(mainPUNode == null){
needInit = true;
} else {
nsp = sc.getSection(mainPUNode);
SectionPanel sp = nsp!=null && nsp instanceof SectionPanel ? ((SectionPanel)nsp) : null;
PersistenceUnitPanel up = (PersistenceUnitPanel) (sp != null && sp.getInnerPanel() != null && sp.getInnerPanel() instanceof PersistenceUnitPanel ? sp.getInnerPanel() : null);
if(up != null) {
up.initEntityList();
}
else {
needInit = true;//at least mark as required to be refreshed
}
}
} else {
needInit = true;//at least mark as required to be refreshed
}
}
}
private class PersistenceView extends SectionView {
private SectionContainer persistenceUnitsCont;
private Node persistenceUnitsNode;
public SectionContainer getPersistenceUnitsCont(){
return persistenceUnitsCont;
}
public Node getPersistenceUnitsNode(){
return persistenceUnitsNode;
}
PersistenceView(){
super(factory);
}
/**
* Initializes the view.
*
* @param pudo the <code>PUDataObject</code> that should be used
* for initializing this view. Must represent a parseable persistence.xml
* deployment descriptor file.
*/
void initialize(PUDataObject pudo){
Persistence persistence = pudo.getPersistence();
PersistenceUnit[] persistenceUnits = persistence.getPersistenceUnit();
Node[] persistenceUnitNode = new Node[persistenceUnits.length];
Children ch = new Children.Array();
for (int i=0;i<persistenceUnits.length;i++) {
//
Node mainPUNode = new ElementLeafNode(NbBundle.getMessage(PersistenceToolBarMVElement.class, "LBL_PU_General"));
// Node for properties
Node propertiesNode = new ElementLeafNode(NbBundle.getMessage(PersistenceToolBarMVElement.class, "LBL_PU_Properties"));
// Container Node for the properties inside the pu
Children puCh = new Children.Array();
puCh.add(new Node[]{mainPUNode, propertiesNode});
persistenceUnitNode[i] = new PersistenceUnitNode(puCh, persistenceUnits[i]);
}
ch.add(persistenceUnitNode);
persistenceUnitsNode = new SectionContainerNode(ch);
persistenceUnitsNode.setDisplayName(NbBundle.getMessage(PersistenceToolBarMVElement.class,"LBL_PersistenceUnits"));
// add panels
persistenceUnitsCont = new SectionContainer(this,persistenceUnitsNode,
NbBundle.getMessage(PersistenceToolBarMVElement.class,"LBL_PersistenceUnits"));
persistenceUnitsCont.setHeaderActions(new javax.swing.Action[]{addAction});
Children rootChildren = new Children.Array();
rootChildren.add(new Node[]{persistenceUnitsNode});
Node root = new AbstractNode(rootChildren);
// creatings section panels for Chapters
SectionContainer[] pan = new SectionContainer[persistenceUnits.length];
for (int i=0; i < persistenceUnits.length; i++) {
pan[i] = new SectionContainer(this, persistenceUnitNode[i],
persistenceUnitNode[i].getDisplayName(), false);
pan[i].setHeaderActions(new javax.swing.Action[]{removeAction});
persistenceUnitsCont.addSection(pan[i]);
Node mainPUNode = persistenceUnitNode[i].getChildren().getNodes()[0];
Node propertiesNode = persistenceUnitNode[i].getChildren().getNodes()[1];
Provider prov = persistenceUnits[i].getProvider()!=null ? ProviderUtil.getProvider(persistenceUnits[i]) : Util.getDefaultProvider(project);
pan[i].addSection(new SectionPanel(this, mainPUNode, mainPUNode.getDisplayName(), persistenceUnits[i], false, false));
pan[i].addSection(new SectionPanel(this, propertiesNode, propertiesNode.getDisplayName(), new PropertiesPanel.PropertiesParamHolder(persistenceUnits[i], prov), false, false));
}
addSection(persistenceUnitsCont);
setRoot(root);
}
@Override
public Error validateView() {
PersistenceValidator validator = new PersistenceValidator((PUDataObject)dObj);
List<Error> result = validator.validate();
if (!result.isEmpty()){
return result.get(0);
}
return null;
}
}
private static class PersistenceUnitNode extends org.openide.nodes.AbstractNode {
PersistenceUnit pu;
PersistenceUnitNode(Children children, PersistenceUnit persistenceUnit) {
super(children);
setDisplayName(persistenceUnit.getName());
setIconBaseWithExtension("org/netbeans/modules/j2ee/persistence/unit/PersistenceIcon.gif"); //NOI18N
this.pu = persistenceUnit;
}
PersistenceUnit getPersistenceUnit(){
return pu;
}
@Override
public HelpCtx getHelpCtx() {
return new HelpCtx(PUDataObject.HELP_ID_DESIGN_PERSISTENCE_UNIT); //NOI18N
}
}
private static class ElementLeafNode extends org.openide.nodes.AbstractNode {
ElementLeafNode(String displayName) {
super(org.openide.nodes.Children.LEAF);
setDisplayName(displayName);
}
@Override
public HelpCtx getHelpCtx() {
//return new HelpCtx(HibernateCfgDataObject.HELP_ID_DESIGN_HIBERNATE_CONFIGURATION); //NOI18N
return null;
}
}
private class ModelListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!puDataObject.isChangedFromUI()) {
// repaint view if the wiew is active and something is changed with elements listed above
MultiViewPerspective selectedPerspective = dObj.getSelectedPerspective();
if (selectedPerspective != null && PUDataObject.PREFERRED_ID_DESIGN.equals(selectedPerspective.preferredID())) {
repaintingTask.schedule(100);
} else {
needInit = true;
}
}
}
}
/**
* Handles adding of a new Persistence Unit via multiview.
*/
private class AddAction extends javax.swing.AbstractAction {
AddAction(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
boolean isContainer = Util.isSupportedJavaEEVersion(project);
final PersistenceUnitWizardPanel panel;
if (isContainer && ProviderUtil.isValidServerInstanceOrNone(project)) {
panel = new PersistenceUnitWizardPanelDS(project, null, true);
} else {
panel = new PersistenceUnitWizardPanelJdbc(project, null, true);
}
final NotifyDescriptor nd = new NotifyDescriptor(
new WrapperPanel(panel),
NbBundle.getMessage(PersistenceToolBarMVElement.class, "LBL_NewPersistenceUnit"),
NotifyDescriptor.OK_CANCEL_OPTION,
NotifyDescriptor.PLAIN_MESSAGE,
null, null
);
panel.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(PersistenceUnitWizardPanel.IS_VALID)) {
Object newvalue = evt.getNewValue();
if (newvalue != null && newvalue instanceof Boolean) {
validateUnitName(panel);
nd.setValid((Boolean) newvalue);
}
}
}
});
if (!panel.isValidPanel()) {
validateUnitName(panel);
nd.setValid(false);
}
Object result = DialogDisplayer.getDefault().notify(nd);
if (result == NotifyDescriptor.OK_OPTION) {
String version=puDataObject.getPersistence().getVersion();
PersistenceUnit punit;
boolean useModelgen = false;
String modelGenLib = null;
if(Persistence.VERSION_2_1.equals(version))
{
useModelgen = true;
punit = new org.netbeans.modules.j2ee.persistence.dd.persistence.model_2_1.PersistenceUnit();
} else if(Persistence.VERSION_2_0.equals(version)) {
useModelgen = true;
punit = new org.netbeans.modules.j2ee.persistence.dd.persistence.model_2_0.PersistenceUnit();
} else {//currently default 1.0
punit = new org.netbeans.modules.j2ee.persistence.dd.persistence.model_1_0.PersistenceUnit();
}
if (isContainer) {
PersistenceUnitWizardPanelDS puPanel = (PersistenceUnitWizardPanelDS) panel;
if (puPanel.getDatasource() != null && !"".equals(puPanel.getDatasource().trim())){
if (puPanel.isJTA()) {
punit.setJtaDataSource(puPanel.getDatasource());
} else {
punit.setNonJtaDataSource(puPanel.getDatasource());
punit.setTransactionType("RESOURCE_LOCAL");
}
}
Provider provider = puPanel.getSelectedProvider();
if (puPanel.isNonDefaultProviderEnabled()) {
punit.setProvider(puPanel.getNonDefaultProvider());
Library lib = PersistenceLibrarySupport.getLibrary(provider);
if (lib != null && !Util.isDefaultProvider(project, provider)) {
Util.addLibraryToProject(project, lib);
modelGenLib = lib.getName()+"modelgen";//NOI18N
provider = null;//to avoid one more addition
}
}
if(provider != null && provider.getAnnotationProcessor() != null){
Library lib = PersistenceLibrarySupport.getLibrary(provider);
if (lib != null){
Util.addLibraryToProject(project, lib, JavaClassPathConstants.PROCESSOR_PATH);
modelGenLib = lib.getName()+"modelgen";//NOI18N
}
}
} else {
PersistenceUnitWizardPanelJdbc puJdbc = (PersistenceUnitWizardPanelJdbc) panel;
punit = ProviderUtil.buildPersistenceUnit(puJdbc.getPersistenceUnitName(), puJdbc.getSelectedProvider(), puJdbc.getPersistenceConnection(), version);
punit.setTransactionType("RESOURCE_LOCAL");
// Explicitly add <exclude-unlisted-classes>false</exclude-unlisted-classes>
// See issue 142575 - desc 10, and issue 180810
if (!Util.isJavaSE(project)) {
punit.setExcludeUnlistedClasses(false);
}
Library lib = PersistenceLibrarySupport.getLibrary(puJdbc.getSelectedProvider());
if (lib != null){
Util.addLibraryToProject(project, lib);
modelGenLib = lib.getName()+"modelgen";//NOI18N
}
JDBCDriver[] driver = JDBCDriverManager.getDefault().getDrivers(puJdbc.getPersistenceConnection().getDriverClass());
PersistenceLibrarySupport.addDriver(project, driver[0]);
}
punit.setName(panel.getPersistenceUnitName());
ProviderUtil.setTableGeneration(punit, panel.getTableGeneration(), project);
puDataObject.addPersistenceUnit(punit);
comp.setLastActive(punit);
//modelgen
if(useModelgen && modelGenLib!=null){
Library mLib = LibraryManager.getDefault().getLibrary(modelGenLib);
if(mLib!=null) {
Util.addLibraryToProject(project, mLib, JavaClassPathConstants.PROCESSOR_PATH);
}//no real need to add modelgen to compile classpath
}
}
}
}
/**
* Checks that given <code>panel</code>'s persistence unit's name is unique; if
* not, sets an appropriate error message to the panel.
*/
private void validateUnitName(PersistenceUnitWizardPanel panel){
try{
if (!panel.isNameUnique()){
panel.setErrorMessage(NbBundle.getMessage(PersistenceUnitWizardDescriptor.class,"ERR_PersistenceUnitNameNotUnique"));
} else {
panel.setErrorMessage(null);
}
} catch (InvalidPersistenceXmlException ipx){
panel.setErrorMessage(NbBundle.getMessage(PersistenceUnitWizardDescriptor.class,"ERR_InvalidPersistenceXml", ipx.getPath()));
}
}
/**
* Handles removing of a Persistence Unit.
*/
private class RemoveAction extends javax.swing.AbstractAction {
RemoveAction(String actionName) {
super(actionName);
}
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
JButton but = (JButton) evt.getSource();
SectionContainer sc = null;
for(Container c=but.getParent(); c!=null; c=c.getParent()){
if(c instanceof SectionContainer){
sc = (SectionContainer) c;
break;
}
}
PersistenceUnitNode pun = (PersistenceUnitNode) sc.getNode();
PersistenceUnit punit = pun.getPersistenceUnit();
org.openide.DialogDescriptor desc = new ConfirmDialog(NbBundle.getMessage(PersistenceToolBarMVElement.class,"LBL_ConfirmRemove", punit.getName()));
java.awt.Dialog dialog = org.openide.DialogDisplayer.getDefault().createDialog(desc);
dialog.setVisible(true);
if (org.openide.DialogDescriptor.OK_OPTION.equals(desc.getValue())) {
sc.removeSection(sc);
puDataObject.removePersistenceUnit(punit);
}
}
@Override
public boolean isEnabled() {
//according to jpa 2.0 there should be at least one persistence unit
boolean disable=puDataObject.getPersistence().sizePersistenceUnit()<=1 && (Double.parseDouble(puDataObject.getPersistence().getVersion())>=Double.parseDouble(Persistence.VERSION_2_0));
return !disable;
}
}
}