Java tutorial
//Copyright (C) 2010 Novabit Informationssysteme GmbH // //This file is part of Nuclos. // //Nuclos is free software: you can redistribute it and/or modify //it under the terms of the GNU Affero General Public License as published by //the Free Software Foundation, either version 3 of the License, or //(at your option) any later version. // //Nuclos is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU Affero General Public License for more details. // //You should have received a copy of the GNU Affero General Public License //along with Nuclos. If not, see <http://www.gnu.org/licenses/>. package org.nuclos.client.common; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.beans.PropertyChangeListener; import java.io.Serializable; import java.lang.ref.WeakReference; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.prefs.Preferences; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListCellRenderer; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import org.apache.commons.lang.NullArgumentException; import org.apache.log4j.Logger; import org.nuclos.client.common.security.SecurityCache; import org.nuclos.client.datasource.NuclosSearchConditionUtils; import org.nuclos.client.entityobject.EntityObjectDelegate; import org.nuclos.client.genericobject.Modules; import org.nuclos.client.layout.wysiwyg.WYSIWYGStringsAndLabels.STATIC_BUTTON; import org.nuclos.client.main.Main; import org.nuclos.client.main.MainController; import org.nuclos.client.main.mainframe.IconResolver; import org.nuclos.client.main.mainframe.MainFrame; import org.nuclos.client.main.mainframe.MainFrameTab; import org.nuclos.client.main.mainframe.workspace.ITabStoreController; import org.nuclos.client.main.mainframe.workspace.TabRestoreController; import org.nuclos.client.masterdata.MasterDataDelegate; import org.nuclos.client.searchfilter.EntitySearchFilter; import org.nuclos.client.searchfilter.SaveFilterController; import org.nuclos.client.searchfilter.SearchFilter; import org.nuclos.client.searchfilter.SearchFilterCache; import org.nuclos.client.searchfilter.SearchFilters; import org.nuclos.client.ui.CenteringPanel; import org.nuclos.client.ui.ColoredLabel; import org.nuclos.client.ui.CommonAbstractAction; import org.nuclos.client.ui.DefaultSelectObjectsPanel; import org.nuclos.client.ui.Errors; import org.nuclos.client.ui.Icons; import org.nuclos.client.ui.SelectObjectsController; import org.nuclos.client.ui.UIUtils; import org.nuclos.client.ui.collect.CollectActionAdapter; import org.nuclos.client.ui.collect.CollectController; import org.nuclos.client.ui.collect.CollectPanel; import org.nuclos.client.ui.collect.CollectState; import org.nuclos.client.ui.collect.CollectStateConstants; import org.nuclos.client.ui.collect.detail.DetailsPanel; import org.nuclos.client.ui.collect.result.NuclosResultController; import org.nuclos.client.ui.collect.result.NuclosSearchResultStrategy; import org.nuclos.client.ui.collect.result.ResultController; import org.nuclos.client.ui.collect.search.ISearchStrategy; import org.nuclos.client.ui.collect.search.SearchPanel; import org.nuclos.client.ui.layoutml.LayoutMLButtonActionListener; import org.nuclos.client.ui.model.ChoiceList; import org.nuclos.common.Actions; import org.nuclos.common.NuclosBusinessException; import org.nuclos.common.NuclosFatalException; import org.nuclos.common.ParameterProvider; import org.nuclos.common.WorkspaceDescription.EntityPreferences; import org.nuclos.common.collect.collectable.Collectable; import org.nuclos.common.collect.collectable.CollectableEntity; import org.nuclos.common.collect.collectable.searchcondition.CollectableSearchCondition; import org.nuclos.common.collect.collectable.searchcondition.SearchConditionUtils; import org.nuclos.common.collect.exception.CollectableFieldFormatException; import org.nuclos.common.collect.exception.CollectableValidationException; import org.nuclos.common.collection.CollectionUtils; import org.nuclos.common.collection.Pair; import org.nuclos.common.dal.vo.EntityFieldMetaDataVO; import org.nuclos.common2.CommonRunnable; import org.nuclos.common2.IdUtils; import org.nuclos.common2.LangUtils; import org.nuclos.common2.PreferencesUtils; import org.nuclos.common2.SpringLocaleDelegate; import org.nuclos.common2.StringUtils; import org.nuclos.common2.XStreamSupport; import org.nuclos.common2.exception.CommonBusinessException; import org.nuclos.common2.exception.CommonFatalException; import org.nuclos.common2.exception.CommonValidationException; import org.nuclos.common2.exception.PreferencesException; import org.nuclos.server.attribute.BadGenericObjectException; import org.nuclos.server.common.NuclosUpdateException; import org.nuclos.server.ruleengine.NuclosBusinessRuleException; import org.nuclos.server.ruleengine.valueobject.RuleVO; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; /** * Base class for all <code>CollectController</code>s in Nucleus. * <br> * <br>Created by Novabit Informationssysteme GmbH * <br>Please visit <a href="http://www.novabit.de">www.novabit.de</a> * * @author <a href="mailto:Christoph.Radig@novabit.de">Christoph.Radig</a> * @version 01.00.00 */ public abstract class NuclosCollectController<Clct extends Collectable> extends CollectController<Clct> { private static final Logger LOG = Logger.getLogger(NuclosCollectController.class); protected String sEntity; protected static final String PREFS_KEY_OUTERSTATE = "outerState"; protected static final String PREFS_KEY_ENTITY = "entity"; protected static final String PREFS_KEY_COLLECTABLEID = "collectableId"; protected static final String PREFS_NODE_SEARCHCONDITION = "searchCondition"; /** * Listener for search filter */ private final ActionListener alSearchFilter = new ActionListener() { @Override public void actionPerformed(ActionEvent ev) { cmdSetCollectableSearchConditionAccordingToFilter(); } }; /** * <code>ActionListener</code> defining actions for buttons in the LayoutML definition. */ private LayoutMLButtonActionListener alLayoutMLButtons; /** * Don't make this public! * * You should use {@link org.nuclos.client.ui.collect.CollectControllerFactorySingleton} * to get an instance. * * @deprecated You should normally do sth. like this:<code><pre> * ResultController<~> rc = new ResultController<~>(); * *CollectController<~> cc = new *CollectController<~>(.., rc); * </code></pre> */ protected NuclosCollectController(String sEntityName, MainFrameTab tabIfAny) { this(NuclosCollectableEntityProvider.getInstance().getCollectableEntity(sEntityName), tabIfAny); this.sEntity = sEntityName; } /** * Don't make this public! * * @deprecated You should normally do sth. like this:<code><pre> * ResultController<~> rc = new ResultController<~>(); * *CollectController<~> cc = new *CollectController<~>(.., rc); * </code></pre> */ protected NuclosCollectController(CollectableEntity clcte, MainFrameTab tabIfAny) { super(clcte, tabIfAny, new NuclosResultController<Clct>(clcte, new NuclosSearchResultStrategy<Clct>())); this.sEntity = clcte.getName(); } /** * You should use {@link org.nuclos.client.ui.collect.CollectControllerFactorySingleton} * to get an instance. * * @deprecated You should normally do sth. like this:<code><pre> * ResultController<~> rc = new ResultController<~>(); * *CollectController<~> cc = new *CollectController<~>(.., rc); * </code></pre> */ protected NuclosCollectController(String sEntityName, MainFrameTab tabIfAny, ResultController<Clct> rc) { this(NuclosCollectableEntityProvider.getInstance().getCollectableEntity(sEntityName), tabIfAny, rc); this.sEntity = sEntityName; } protected NuclosCollectController(CollectableEntity clcte, MainFrameTab tabIfAny, ResultController<Clct> rc) { super(clcte, tabIfAny, rc); this.sEntity = clcte.getName(); } public String getEntity() { return sEntity; } // The following is a trial to encapsulate the data access for specific controllers. @see CollectModel // /** // * @return the model used in this controller. // * @todo make abstract and move to CollectController // */ // public CollectModel<Clct> getModel() { // return null; // } // // @Deprecated // protected Clct newCollectable() { // return this.getModel().newCollectable(); // } // // @Deprecated // protected Clct insertCollectable(Clct clctNew) throws CommonBusinessException { // return this.getModel().insertCollectable(clctNew); // } // // @Deprecated // protected Clct updateCollectable(Clct clct, Object oAdditionalData) throws CommonBusinessException { // return this.getModel().updateCollectable(clct, oAdditionalData); // } // // @Deprecated // protected void deleteCollectable(Clct clct) throws CommonBusinessException { // this.getModel().deleteCollectable(clct); // } /** * @todo this method is misused - it sets shortcuts for many things other than tabs... * @param frame */ @Override protected void setupShortcutsForTabs(MainFrameTab frame) { final CollectPanel<Clct> pnlCollect = this.getCollectPanel(); final DetailsPanel pnlDetails = this.getDetailsPanel(); final Action actSelectSearchTab = new AbstractAction() { @Override public void actionPerformed(ActionEvent ev) { if (pnlCollect.isTabbedPaneEnabledAt(CollectPanel.TAB_SEARCH)) { pnlCollect.setTabbedPaneSelectedComponent(getSearchPanel()); } } }; KeyBindingProvider.bindActionToComponent(KeyBindingProvider.ACTIVATE_SEARCH_PANEL_1, actSelectSearchTab, pnlCollect); KeyBindingProvider.bindActionToComponent(KeyBindingProvider.ACTIVATE_SEARCH_PANEL_2, actSelectSearchTab, pnlCollect); //TODO This is a workaround. The detailpanel should keep the focus final Action actGrabFocus = new AbstractAction() { @Override public void actionPerformed(ActionEvent ev) { pnlDetails.grabFocus(); } }; /** * A <code>ChainedAction</code> is an action composed of a primary and a secondary action. * It behaves exactly like the primary action, except that additionally, the secondary action is performed * after the primary action. */ class ChainedAction implements Action { private final Action actPrimary; private final Action actSecondary; public ChainedAction(Action actPrimary, Action actSecondary) { this.actPrimary = actPrimary; this.actSecondary = actSecondary; } @Override public void addPropertyChangeListener(PropertyChangeListener listener) { actPrimary.addPropertyChangeListener(listener); } @Override public Object getValue(String sKey) { return actPrimary.getValue(sKey); } @Override public boolean isEnabled() { return actPrimary.isEnabled(); } @Override public void putValue(String sKey, Object oValue) { actPrimary.putValue(sKey, oValue); } @Override public void removePropertyChangeListener(PropertyChangeListener listener) { actPrimary.removePropertyChangeListener(listener); } @Override public void setEnabled(boolean bEnabled) { actPrimary.setEnabled(bEnabled); } @Override public void actionPerformed(ActionEvent ev) { actPrimary.actionPerformed(ev); actSecondary.actionPerformed(ev); } } //final Action actRefresh = new ChainedAction(this.getRefreshCurrentCollectableAction(), actGrabFocus); this.getCollectPanel().setTabbedPaneToolTipTextAt(CollectPanel.TAB_SEARCH, getSpringLocaleDelegate().getMessage("NuclosCollectController.13", "Suche (F7) (Strg+F)")); this.getCollectPanel().setTabbedPaneToolTipTextAt(CollectPanel.TAB_RESULT, getSpringLocaleDelegate().getMessage("NuclosCollectController.7", "Ergebnis (F8)")); this.getCollectPanel().setTabbedPaneToolTipTextAt(CollectPanel.TAB_DETAILS, getSpringLocaleDelegate().getMessage("NuclosCollectController.3", "Details (F2)")); // the search action KeyBindingProvider.bindActionToComponent(KeyBindingProvider.START_SEARCH, this.getSearchAction(), pnlCollect); KeyBinding keybinding = KeyBindingProvider.REFRESH; // the refresh action KeyBindingProvider.removeActionFromComponent(keybinding, pnlDetails); pnlDetails.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(keybinding.getKeystroke(), keybinding.getKey()); pnlDetails.getActionMap().put(keybinding.getKey(), this.getRefreshCurrentCollectableAction()); KeyBindingProvider.removeActionFromComponent(keybinding, getResultPanel()); getResultPanel().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(keybinding.getKeystroke(), keybinding.getKey()); getResultPanel().getActionMap().put(keybinding.getKey(), getResultPanel().btnRefresh.getAction()); // the new action KeyBindingProvider.bindActionToComponent(KeyBindingProvider.NEW, this.getNewAction(), pnlDetails); // the new with search values action KeyBindingProvider.bindActionToComponent(KeyBindingProvider.NEW_SEARCHVALUE, this.getNewWithSearchValuesAction(), pnlCollect); // the save action KeyBindingProvider.bindActionToComponent(KeyBindingProvider.SAVE_1, this.getSaveAction(), pnlCollect); KeyBindingProvider.bindActionToComponent(KeyBindingProvider.SAVE_2, this.getSaveAction(), pnlCollect); // first the navigation actions are performed and then the focus is grabbed: final Action actFirst = new ChainedAction(this.getFirstAction(), actGrabFocus); final Action actLast = new ChainedAction(this.getLastAction(), actGrabFocus); final Action actPrevious = new ChainedAction(this.getPreviousAction(), actGrabFocus); final Action actNext = new ChainedAction(this.getNextAction(), actGrabFocus); // the first action KeyBindingProvider.bindActionToComponent(KeyBindingProvider.FIRST, actFirst, pnlDetails); pnlDetails.btnFirst.setAction(actFirst); // the last action KeyBindingProvider.bindActionToComponent(KeyBindingProvider.LAST, actLast, pnlDetails); pnlDetails.btnLast.setAction(actLast); // the previous action KeyBindingProvider.bindActionToComponent(KeyBindingProvider.PREVIOUS_1, actPrevious, pnlDetails); KeyBindingProvider.bindActionToComponent(KeyBindingProvider.PREVIOUS_2, actPrevious, pnlDetails); pnlDetails.btnPrevious.setAction(actPrevious); // the next action KeyBindingProvider.bindActionToComponent(KeyBindingProvider.NEXT_1, actNext, pnlDetails); KeyBindingProvider.bindActionToComponent(KeyBindingProvider.NEXT_2, actNext, pnlDetails); pnlDetails.btnNext.setAction(actNext); Action actClose = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { getTab().dispose(); } }; KeyBindingProvider.bindActionToComponent(KeyBindingProvider.CLOSE_CHILD, actClose, pnlCollect); if (getResultPanel() != null && getResultTable() != null) { final JButton btnEdit = getResultPanel().btnEdit; KeyBindingProvider.bindActionToComponent(KeyBindingProvider.EDIT_1, btnEdit.getAction(), getResultTable()); if (getResultTable().getActionMap().get(KeyBindingProvider.EDIT_2.getKey()) == null) KeyBindingProvider.bindActionToComponent(KeyBindingProvider.EDIT_2, btnEdit.getAction(), getResultTable()); } } @Override protected Preferences getUserPreferencesRoot() { return org.nuclos.common2.ClientPreferences.getUserPreferences(); } @Override public void lockFrame(boolean bLock) { super.lockFrame(bLock); } /** * @return false (default) */ @Override protected boolean isMultiEditAllowed() { return false; } /** * @deprecated Move to ResultController hierarchy and make protected again. * It would be far better, if the class (hierarchy) would known that search * should be single- or multi-threaded. */ @Override public boolean isMultiThreadingEnabled() { // enable/disable multithreading here: // return false; return true; } /** * @return Is this <code>CollectController</code> restorable from preferences? Default: true. */ public boolean isRestorableFromPreferences() { return true; } private static class RestorePreferences implements Serializable { private static final long serialVersionUID = 6637996725938917463L; String entity; Integer iCollectState; Long objectId; CollectableSearchCondition searchCondition; Map<String, String> inheritControllerPreferences = new HashMap<String, String>(1); String customUsage; } private static String toXML(RestorePreferences rp) { final XStreamSupport xs = XStreamSupport.getInstance(); final XStream xstream = xs.getXStream(); try { return xstream.toXML(rp); } finally { xs.returnXStream(xstream); } } private static RestorePreferences fromXML(String xml) { final XStreamSupport xs = XStreamSupport.getInstance(); final XStream xstream = xs.getXStream(); try { return (RestorePreferences) xstream.fromXML(xml); } finally { xs.returnXStream(xstream); } } protected void storeInstanceStateToPreferences(Map<String, String> inheritControllerPreferences) { } protected void restoreInstanceStateFromPreferences(Map<String, String> inheritControllerPreferences) { } public static class NuclosCollectTabStoreController implements ITabStoreController { private WeakReference<NuclosCollectController<?>> refCtl; public NuclosCollectTabStoreController(NuclosCollectController<?> ctl) { this.refCtl = new WeakReference<NuclosCollectController<?>>(ctl); } @Override public String getPreferencesXML() { final NuclosCollectController<?> ctl = refCtl.get(); if (ctl == null) { throw new NullPointerException("Controller has already been gc'ed"); } final RestorePreferences rp = new RestorePreferences(); rp.entity = ctl.getEntity(); rp.customUsage = ctl.getCustomUsage(); try { if (ctl.getCollectStateModel().getOuterState() == CollectState.OUTERSTATE_DETAILS) { rp.iCollectState = CollectState.OUTERSTATE_DETAILS; ctl.writeCurrentCollectableToPreferences(rp); } ctl.writeStateToPreferences(rp); } catch (Exception e) { LOG.warn("Preferences not completely stored.", e); } ctl.storeInstanceStateToPreferences(rp.inheritControllerPreferences); return toXML(rp); } @Override public Class<?> getTabRestoreControllerClass() { return NuclosCollectTabRestoreController.class; } } public static class NuclosCollectTabRestoreController extends TabRestoreController { @Override public void restoreFromPreferences(String preferencesXML, MainFrameTab tab) throws Exception { RestorePreferences rp = fromXML(preferencesXML); NuclosCollectController<?> ctl = createFromPreferences(rp, tab); final MainController mc = Main.getInstance().getMainController(); mc.initMainFrameTab(ctl, tab); // Main.getMainController().addMainFrameTab would be called from listener inside of initMainFrameTab, but only when tab added. // During restore the tabs are already added, so we need to do this manually. mc.addMainFrameTab(tab, ctl); ctl.restoreInstanceStateFromPreferences(rp.inheritControllerPreferences); } } /** * @param prefs * @param parent * @return a new <code>NuclosCollectController</code> with the state read from the preferences. */ @Deprecated public static NuclosCollectController<?> createFromPreferences(final Preferences prefs) throws PreferencesException { final String sEntity = prefs.get(PREFS_KEY_ENTITY, null); if (sEntity == null) { throw new PreferencesException(SpringLocaleDelegate.getInstance().getMessage( "NuclosCollectController.6", "Entit\u00e4t {0} fehlt in den Benutzereinstellungen.", sEntity)); } boolean allowed; allowed = SecurityCache.getInstance().isReadAllowedForModule(sEntity, null) || SecurityCache.getInstance().isReadAllowedForMasterData(sEntity); if (!allowed) { throw new PreferencesException( SpringLocaleDelegate.getInstance().getMessage("NuclosCollectController.17", "Sie haben kein Recht die Entit\u00e4t ''{0}'' zu verwenden.", sEntity)); } try { final NuclosCollectController<?> result = NuclosCollectControllerFactory.getInstance() .newCollectController(sEntity, null, ClientParameterProvider.getInstance() .getValue(ParameterProvider.KEY_LAYOUT_CUSTOM_KEY)); final int iCollectState = result.restoreStateFromPreferences(prefs); UIUtils.runCommandLaterForTabbedPane(MainFrame.getPredefinedEntityOpenLocation(sEntity), new CommonRunnable() { // This must be done later as reloading the layout in restoreStateFromPreferences is done later also: @Override public void run() throws CommonBusinessException { switch (iCollectState) { case CollectState.OUTERSTATE_SEARCH: result.runSearch(false); break; case CollectState.OUTERSTATE_RESULT: result.runViewAll(false); break; case CollectState.OUTERSTATE_DETAILS: final Collectable clct = result.getCurrentCollectableFromPreferences(prefs); if (clct == null) { result.runNew(false); } else { ((NuclosCollectController) result).runViewSingleCollectable(clct, false); } break; default: throw new PreferencesException(SpringLocaleDelegate.getInstance().getMessage( "NuclosCollectController.14", "Ung\u00fcltiger Erfassungsstatus in den Benutzereinstellungen: {0}", iCollectState)); } } }); return result; } catch (CommonBusinessException ex) { throw new PreferencesException(ex.getMessage(), ex); } } /** * * @param rp * @param tabIfAny * @return * @throws CommonBusinessException */ public static NuclosCollectController<?> createFromPreferences(final RestorePreferences rp, MainFrameTab tabIfAny) throws CommonBusinessException { boolean allowed; allowed = SecurityCache.getInstance().isReadAllowedForModule(rp.entity, null) || SecurityCache.getInstance().isReadAllowedForMasterData(rp.entity); if (!allowed) { throw new PreferencesException( SpringLocaleDelegate.getInstance().getMessage("NuclosCollectController.17", "Sie haben kein Recht die Entit\u00e4t ''{0}'' zu verwenden.", rp.entity)); } final NuclosCollectController<?> result = NuclosCollectControllerFactory.getInstance() .newCollectController(rp.entity, tabIfAny, rp.customUsage != null ? rp.customUsage : ClientParameterProvider.getInstance().getValue(ParameterProvider.KEY_LAYOUT_CUSTOM_KEY)); final int cs = result.restoreStateFromPreferences(rp.iCollectState, rp.searchCondition); UIUtils.runCommandLater( tabIfAny != null ? tabIfAny : Main.getInstance().getMainFrame().getHomePane().getComponentPanel(), new CommonRunnable() { // This must be done later as reloading the layout in restoreStateFromPreferences is done later also: @Override public void run() throws CommonBusinessException { switch (cs) { case CollectState.OUTERSTATE_SEARCH: result.runSearch(false); break; case CollectState.OUTERSTATE_RESULT: result.runViewAll(false); break; case CollectState.OUTERSTATE_DETAILS: if (rp.objectId == null) { result.runNew(false); } else { ((NuclosCollectController) result) .runViewSingleCollectableWithId(rp.objectId.intValue(), false); } break; default: throw new PreferencesException( SpringLocaleDelegate.getInstance().getMessage("NuclosCollectController.14", "Ung\u00fcltiger Erfassungsstatus in den Benutzereinstellungen: {0}", rp.iCollectState)); } } }); return result; } /** * restores the state of this <code>CollectController</code> from the preferences. * @param iCollectState * @param cond * @return * @throws CommonBusinessException */ protected int restoreStateFromPreferences(Integer iCollectState, CollectableSearchCondition cond) throws CommonBusinessException { if (this.isSearchPanelAvailable()) { assert this.getCollectStateModel().getOuterState() == CollectState.OUTERSTATE_UNDEFINED; // Always set Search mode initially, to restore the search criteria. // Later, the previous state is restored. if (cond != null) { this.setCollectState(CollectState.OUTERSTATE_SEARCH, CollectState.SEARCHMODE_UNSYNCHED); this.restoreSearchCriteriaFromPreferences(cond); } } // restore collect state: return LangUtils.defaultIfNull(iCollectState, CollectState.OUTERSTATE_UNDEFINED); } /** * restores the state of this <code>CollectController</code> from the preferences. * @param prefs * @return the stored collect state. * @throws NuclosBusinessException */ @Deprecated protected int restoreStateFromPreferences(Preferences prefs) throws CommonBusinessException { if (this.isSearchPanelAvailable()) { assert this.getCollectStateModel().getOuterState() == CollectState.OUTERSTATE_UNDEFINED; final CollectableSearchCondition cond = SearchConditionUtils.getSearchCondition( prefs.node(PREFS_NODE_SEARCHCONDITION), this.getCollectableEntity().getName()); // Always set Search mode initially, to restore the search criteria. // Later, the previous state is restored. if (cond != null) { this.setCollectState(CollectState.OUTERSTATE_SEARCH, CollectState.SEARCHMODE_UNSYNCHED); this.restoreSearchCriteriaFromPreferences(prefs); } } // restore collect state: return prefs.getInt(PREFS_KEY_OUTERSTATE, CollectState.OUTERSTATE_UNDEFINED); } /** * @param prefs * @throws CollectableFieldFormatException * @throws PreferencesException * @precondition this.isSearchPanelVisible() */ protected void writeSearchCriteriaToPreferences(RestorePreferences rp) throws CommonBusinessException { // write current search criteria (which may differ from the current search filter's criteria): // We don't call makeConsistent (see below), but we want to get the last input of a table cell editor, if any: this.stopEditingInSearch(); // Note that makeConsistent is not called here. If the search condition is incomplete, the differences in the view // to the model are ignored. This seems to be better than throwing an exception here and not storing the search condition at all: final CollectableSearchCondition cond = this.getCollectableSearchConditionFromSearchPanel(false); rp.searchCondition = cond; LOG.debug("Wrote searchcondition to prefs: " + LangUtils.toString(cond)); } /** * * @param cond * @throws CommonBusinessException * @precondition this.isSearchPanelVisible() */ protected void restoreSearchCriteriaFromPreferences(CollectableSearchCondition cond) throws CommonBusinessException { if (!this.isSearchPanelAvailable()) { throw new IllegalStateException("!isSearchPanelVisible()"); } this.setCollectableSearchConditionInSearchPanel(NuclosSearchConditionUtils.restorePlainSubConditions(cond)); try { LOG.debug("restored searchcondition from prefs: " + LangUtils.toString(getSearchStrategy().getCollectableSearchCondition())); } catch (CollectableFieldFormatException ex) { LOG.debug("Exception thrown in log statement", ex); } } /** * @param prefs * @throws CommonBusinessException * @precondition this.isSearchPanelVisible() */ @Deprecated protected void restoreSearchCriteriaFromPreferences(Preferences prefs) throws CommonBusinessException { if (!this.isSearchPanelAvailable()) { throw new IllegalStateException("!isSearchPanelVisible()"); } // restore search condition: final CollectableSearchCondition cond = SearchConditionUtils .getSearchCondition(prefs.node(PREFS_NODE_SEARCHCONDITION), this.getCollectableEntity().getName()); this.restoreSearchCriteriaFromPreferences(cond); } /** * writes the state of this <code>CollectController</code> to the preferences. * @param prefs * @throws CommonBusinessException * @throws PreferencesException */ protected void writeStateToPreferences(RestorePreferences rp) throws CommonBusinessException { // write collect state: rp.iCollectState = this.getCollectStateModel().getOuterState(); if (this.isSearchPanelAvailable()) { this.writeSearchCriteriaToPreferences(rp); } } /** * writes the current collectable to the preferences. * @param prefs */ protected void writeCurrentCollectableToPreferences(RestorePreferences rp) { this.writeSerializableCurrentCollectableIdToPreferences(rp); } /** * reads the current collectable from the preferences. * @param prefs * @return the current collectable, if any. */ protected Clct getCurrentCollectableFromPreferences(Preferences prefs) throws PreferencesException, CommonBusinessException { final Object oId = PreferencesUtils.getSerializable(prefs, PREFS_KEY_COLLECTABLEID); return (oId == null) ? null : this.findCollectableById(this.getEntityName(), oId); } /** * makes the given Collectable complete, if it isn't already. * @param clct * @return * @throws CommonBusinessException * @postcondition isCollectableComplete(result) * @postcondition isCollectableComplete(clct) --> result == clct * @todo pull down to CollectController? */ protected final Clct getCompleteCollectable(Clct clct) throws CommonBusinessException { final ISearchStrategy<Clct> ss = getSearchStrategy(); final Clct result = ss.isCollectableComplete(clct) ? clct : this.readCollectable(clct); assert ss.isCollectableComplete(result); assert !ss.isCollectableComplete(clct) || result == clct; return result; } /** * runs the controller. If there is a search panel for this entity, starts with the search panel. Otherwise, * starts with the result panel. */ public void run() throws CommonBusinessException { this.run(this.isSearchPanelAvailable()); } /** * runs this controller, starting with the search panel or with the result panel, depending on the parameter. * @param bStartWithSearchPanel */ protected void run(boolean bStartWithSearchPanel) throws CommonBusinessException { if (bStartWithSearchPanel) { this.runSearch(); } else { this.runViewAll(); } } /** * writes the current collectable id to the preferences. The collectable id must be serializable. * @param prefs * @throws PreferencesException */ protected void writeSerializableCurrentCollectableIdToPreferences(RestorePreferences rp) { final Object oId = this.getSelectedCollectableId(); LOG.debug("writeSerializableCurrentCollectableIdToPreferences: oId = " + oId); if ((oId != null) && !(oId instanceof Serializable)) { throw new NuclosFatalException("The CollectableId is not serializable");//Die CollectableId ist nicht serialisierbar. } rp.objectId = new Long(((Integer) oId).longValue()); } @Override protected void handleSaveException(CommonBusinessException ex, String sMessage1) throws CommonBusinessException { if (ex instanceof CollectableValidationException) { handleCollectableValidationException((CollectableValidationException) ex, sMessage1); } else { try { throw ex; } catch (BadGenericObjectException ex2) { Errors.getInstance().showExceptionDialog(this.getTab(), null, ex2); } catch (NuclosUpdateException ex2) { /** @todo this is a workaround. @see GenericObjectDelegate.update */ Errors.getInstance().showExceptionDialog(this.getTab(), ex2); } catch (NuclosBusinessRuleException ex2) { Errors.getInstance().showExceptionDialog(this.getTab(), getSpringLocaleDelegate().getMessage("NuclosCollectController.1", "{0}, da das Speichern eine Gesch\u00e4ftsregel verletzen w\u00fcrde.", sMessage1), ex2); } } } /** * @todo refactor viewAll()! * * @deprecated Move to ResultController hierarchy. */ @Override protected void viewAll() throws CommonBusinessException { getResultController().getSearchResultStrategy().refreshResult(); } /** * translates Boolean fields by mapping <code>null</code> to <code>false</code> as there are no nullable * booleans in Nucleus. * @param clctCurrent * @param clcteCurrent * @precondition clctCurrent != null * @precondition isCollectableComplete(clctCurrent) * @precondition clcteCurrent != null */ @Override protected void prepareCollectableForSaving(Clct clctCurrent, CollectableEntity clcteCurrent) { if (clctCurrent == null) { throw new NullArgumentException("clctCurrent"); } if (!getSearchStrategy().isCollectableComplete(clctCurrent)) { throw new IllegalArgumentException("clctCurrent"); } if (clcteCurrent == null) { throw new NullArgumentException("clcteCurrent"); } super.prepareCollectableForSaving(clctCurrent, clcteCurrent); Utils.prepareCollectableForSaving(clctCurrent, clcteCurrent); } private static class MyLayoutMLButtonActionListener<Clct extends Collectable> extends LayoutMLButtonActionListener { private WeakReference<CollectController<Clct>> refCc; private MyLayoutMLButtonActionListener(CollectController<Clct> cc) { this.refCc = new WeakReference<CollectController<Clct>>(cc); } @Override public void actionPerformed(ActionEvent ev) { final CollectController<Clct> cc = refCc.get(); if (cc == null) { return; } final String sActionCommand = ev.getActionCommand(); //NUCLOSINT-743 State and Rule Button Action String targetState = "_targetState="; String ruletoexecute = "_ruletoexecute="; String generatortoexecute = "_generatortoexecute="; try { if (sActionCommand.contains(STATIC_BUTTON.STATE_CHANGE_ACTION + targetState)) { Properties stateProperties = new Properties(); String state = sActionCommand.substring( sActionCommand.indexOf(targetState) + targetState.length(), sActionCommand.length()); stateProperties.put("targetState", state); ((CollectActionAdapter<Clct>) Class.forName(STATIC_BUTTON.STATE_CHANGE_ACTION).newInstance()) .run((JButton) ev.getSource(), cc, stateProperties); } else if (sActionCommand.contains(STATIC_BUTTON.EXECUTE_RULE_ACTION + ruletoexecute)) { Properties ruleProperties = new Properties(); String ruleId = sActionCommand.substring( sActionCommand.indexOf(ruletoexecute) + ruletoexecute.length(), sActionCommand.length()); ruleProperties.put("ruletoexecute", ruleId); ((CollectActionAdapter<Clct>) Class.forName(STATIC_BUTTON.EXECUTE_RULE_ACTION).newInstance()) .run((JButton) ev.getSource(), cc, ruleProperties); } else if (sActionCommand.contains(STATIC_BUTTON.GENERATOR_ACTION + generatortoexecute)) { Properties generatorProperties = new Properties(); String generatorId = sActionCommand.substring( sActionCommand.indexOf(generatortoexecute) + generatortoexecute.length(), sActionCommand.length()); generatorProperties.put("generatortoexecute", generatorId); ((CollectActionAdapter<Clct>) Class.forName(STATIC_BUTTON.GENERATOR_ACTION).newInstance()) .run((JButton) ev.getSource(), cc, generatorProperties); } else { ((CollectActionAdapter<Clct>) Class.forName(sActionCommand).newInstance()) .run((JButton) ev.getSource(), cc, new Properties()); } } catch (InstantiationException ex) { throw new CommonFatalException(ex); } catch (IllegalAccessException ex) { throw new CommonFatalException(ex); } catch (ClassNotFoundException ex) { throw new CommonFatalException(ex); } } @Override public boolean enableParentComponent(String sActionCommand) { if (sActionCommand == null) return false; final CollectController<Clct> cc = refCc.get(); if (cc == null) { return false; } boolean result = false; //NUCLOSINT-743 State and Rule Button Action String targetState = "_targetState="; String ruletoexecute = "_ruletoexecute="; String generatortoexecute = "_generatortoexecute="; try { if (sActionCommand.contains(STATIC_BUTTON.STATE_CHANGE_ACTION + targetState)) { Properties stateProperties = new Properties(); String state = sActionCommand.substring( sActionCommand.indexOf(targetState) + targetState.length(), sActionCommand.length()); stateProperties.put("targetState", state); result = ((CollectActionAdapter<Clct>) Class.forName(STATIC_BUTTON.STATE_CHANGE_ACTION) .newInstance()).isRunnable(cc, stateProperties); } else if (sActionCommand.contains(STATIC_BUTTON.EXECUTE_RULE_ACTION + ruletoexecute)) { Properties ruleProperties = new Properties(); String ruleId = sActionCommand.substring( sActionCommand.indexOf(ruletoexecute) + ruletoexecute.length(), sActionCommand.length()); ruleProperties.put("ruletoexecute", ruleId); result = ((CollectActionAdapter<Clct>) Class.forName(STATIC_BUTTON.EXECUTE_RULE_ACTION) .newInstance()).isRunnable(cc, ruleProperties); } else if (sActionCommand.contains(STATIC_BUTTON.GENERATOR_ACTION + generatortoexecute)) { Properties generatorProperties = new Properties(); String generatorId = sActionCommand.substring( sActionCommand.indexOf(generatortoexecute) + generatortoexecute.length(), sActionCommand.length()); generatorProperties.put("generatortoexecute", generatorId); result = ((CollectActionAdapter<Clct>) Class.forName(STATIC_BUTTON.GENERATOR_ACTION) .newInstance()).isRunnable(cc, generatorProperties); } else { result = ((CollectActionAdapter<Clct>) Class.forName(sActionCommand).newInstance()) .isRunnable(cc, new Properties()); } } catch (InstantiationException ex) { throw new CommonFatalException(ex); } catch (IllegalAccessException ex) { throw new CommonFatalException(ex); } catch (ClassNotFoundException ex) { throw new CommonFatalException(ex); } return result; } } /** * @return <code>ActionListener</code> defining actions for buttons in the LayoutML definition. May be <code>null</code>. */ protected LayoutMLButtonActionListener getLayoutMLButtonsActionListener() { if (alLayoutMLButtons == null) { alLayoutMLButtons = new MyLayoutMLButtonActionListener<Clct>(NuclosCollectController.this); } return alLayoutMLButtons; } protected void resetLayoutMLButtonsActionListener() { alLayoutMLButtons = null; } protected void setupSearchToolBar() { final Action actSaveFilter = new CommonAbstractAction( getSpringLocaleDelegate().getMessage("NuclosCollectController.9", "Filter speichern"), Icons.getInstance().getIconSave16(), getSpringLocaleDelegate().getMessage( "NuclosCollectController.5", "Eingestelltes Suchkriterium als Filter speichern")) { @Override public void actionPerformed(ActionEvent ev) { cmdSaveFilter(); } }; final Action actRemoveFilter = new CommonAbstractAction( getSpringLocaleDelegate().getMessage("NuclosCollectController.8", "Filter l\u00f6schen"), Icons.getInstance().getIconDelete16(), getSpringLocaleDelegate() .getMessage("NuclosCollectController.2", "Ausgew\u00e4hlten Filter l\u00f6schen")) { @Override public void actionPerformed(ActionEvent ev) { cmdRemoveFilter(); } }; //result.add(Box.createHorizontalStrut(5)); CenteringPanel cpSearchFilter = new CenteringPanel(getSearchPanel().cmbbxSearchFilter) { @Override public Dimension getMinimumSize() { return this.getCenteredComponent().getMinimumSize(); } @Override public Dimension getMaximumSize() { return this.getCenteredComponent().getPreferredSize(); } }; cpSearchFilter.setOpaque(false); ColoredLabel bl = new ColoredLabel(cpSearchFilter, getSpringLocaleDelegate().getMessage("CollectController.Search.Filter", "Filter")); bl.setName("blChooseFilter"); this.getSearchPanel().addToolBarComponent(bl); //result.add(cpSearchFilter); //result.add(Box.createHorizontalStrut(2)); this.getSearchPanel().addPopupExtraSeparator(); JMenuItem btnSaveFilter = this.getSearchPanel().addPopupExtraMenuItem(new JMenuItem(actSaveFilter)); JMenuItem btnRemoveFilter = this.getSearchPanel().addPopupExtraMenuItem(new JMenuItem(actRemoveFilter)); //final JButton btnSaveFilter = result.add(actSaveFilter); //final JButton btnRemoveFilter = result.add(actRemoveFilter); // disable the remove filter action initially: actRemoveFilter.setEnabled(false); btnSaveFilter.setName("btnSaveFilter"); btnRemoveFilter.setName("btnRemoveFilter"); getSearchPanel().cmbbxSearchFilter.setName("cmbbxSearchFilter"); getSearchPanel().cmbbxSearchFilter.setToolTipText(getSpringLocaleDelegate() .getMessage("NuclosCollectController.15", "W\u00e4hlen Sie hier einen Suchfilter aus")); getSearchPanel().cmbbxSearchFilter.addActionListener(this.alSearchFilter); // set tool tips dynamically: getSearchPanel().cmbbxSearchFilter.setRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList lst, Object oValue, int index, boolean bSelected, boolean bCellHasFocus) { final JComponent result = (JComponent) super.getListCellRendererComponent(lst, oValue, index, bSelected, bCellHasFocus); String sToolTip = null; if (oValue != null) { final SearchFilter filter = (SearchFilter) oValue; if (result instanceof JLabel && !StringUtils.isNullOrEmpty(filter.getLabelResourceId())) { ((JLabel) result).setText(getSpringLocaleDelegate() .getTextFallback(filter.getLabelResourceId(), filter.getName())); } if (!StringUtils.isNullOrEmpty(filter.getDescriptionResourceId())) { sToolTip = getSpringLocaleDelegate().getTextFallback(filter.getDescriptionResourceId(), filter.getDescriptionResourceId()); } else { sToolTip = filter.getDescription(); } if (filter.getOwner() != null && !(filter.getOwner().equals(Main.getInstance().getMainController().getUserName()))) { sToolTip = sToolTip + " (" + filter.getOwner() + ")"; } result.setToolTipText(sToolTip); } return result; } }); // set the tool tip for the combobox also, as the tool tip for the renderer seems to be // taken in dropped down items only: getSearchPanel().cmbbxSearchFilter.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent ev) { final boolean bSelected = (ev.getStateChange() == ItemEvent.SELECTED); boolean bRegularFilterSelected = bSelected; String sToolTip = null; if (bSelected) { final SearchFilter filter = (SearchFilter) ev.getItem(); assert filter != null; sToolTip = filter.getDescription(); LOG.debug("Filter selected: " + filter.getName()); bRegularFilterSelected = !filter.isDefaultFilter(); } getSearchPanel().cmbbxSearchFilter.setToolTipText(sToolTip); // enable/disable remove filter action - the empty filter cannot be removed: actRemoveFilter.setEnabled(bRegularFilterSelected); } }); //return result; } /** * Command: save filter */ protected void cmdSaveFilter() { UIUtils.runCommand(this.getTab(), new CommonRunnable() { @Override public void run() throws CommonValidationException { if (!stopEditingInSearch()) { throw new CommonValidationException( getSpringLocaleDelegate().getMessage("NuclosCollectController.4", "Die eingegebene Suchbedingung ist ung\u00fcltig bzw. unvollst\u00e4ndig.")); } try { final SearchFilter filterSelected = getSelectedSearchFilter(); SearchFilter filterCurrent = getCurrentSearchFilterFromSearchPanel(); final DefaultComboBoxModel model = (DefaultComboBoxModel) getSearchFilterComboBox().getModel(); final SaveFilterController.Command cmd = new SaveFilterController(getTab(), getSearchFilters()) .runSave(filterSelected, filterCurrent); switch (cmd) { case None: // do nothing break; case Overwrite: selectDefaultFilter(); getSearchFilterComboBox().removeItem(filterSelected); // note that there is no "break" here! case New: filterCurrent = SearchFilterCache.getInstance().getSearchFilter(filterCurrent.getName(), filterCurrent.getOwner()); model.addElement(filterCurrent); UIUtils.ensureMinimumSize(getTab()); getSearchFilterComboBox().setSelectedItem(filterCurrent); break; default: assert false; } } catch (CommonBusinessException ex) { Errors.getInstance().showExceptionDialog(getTab(), ex); } } }); } /** * command: remove filter */ protected void cmdRemoveFilter() { final SearchFilter filter = getSelectedSearchFilter(); if (filter != null) { if (JOptionPane.showConfirmDialog(this.getTab(), getSpringLocaleDelegate().getMessage("NuclosCollectController.16", "Wollen Sie den Filter \"{0}\" wirklich l\u00f6schen?", filter.getName()), "Filter l\u00f6schen", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) { UIUtils.runCommand(this.getTab(), new CommonRunnable() { @Override public void run() throws NuclosBusinessException { getSearchFilters().remove(filter); refreshFilterView(); refreshFastFilter(); } }); } } } /** * @return empty search filter to be used as default */ private SearchFilter newDefaultFilter() { final SearchFilter result = getSearchFilters().newDefaultFilter(); return result; } protected void refreshFastFilter() { getResultPanel().getSearchFilterBar().setSearchFilters(getSearchFilters()); } /** * refreshes the combobox containing the filters */ protected void refreshFilterView() { // remember selected filter, if any: final SearchFilter filterSelected = getSelectedSearchFilter(); final List<? extends SearchFilter> lstFilters; try { lstFilters = getSearchFilters().getAll(); } catch (PreferencesException ex) { throw new NuclosFatalException(ex); } final DefaultComboBoxModel model = (DefaultComboBoxModel) this.getSearchFilterComboBox().getModel(); // don't fire changed events here: this.getSearchFilterComboBox().removeActionListener(this.alSearchFilter); try { model.removeAllElements(); model.addElement(newDefaultFilter()); for (SearchFilter filter : lstFilters) { model.addElement(filter); } // try to restore the previously selected filter, if any: if (filterSelected != null) { setSelectedSearchFilter(filterSelected); } } finally { getSearchFilterComboBox().addActionListener(this.alSearchFilter); } // perform alSearchFilter's action manually: this.alSearchFilter.actionPerformed(null); } protected SearchFilters getSearchFilters() { return SearchFilters.forEntity(this.getEntityName()); } protected SearchFilter getCurrentSearchFilterFromSearchPanel() throws CommonBusinessException { final EntitySearchFilter result = new EntitySearchFilter(); result.setSearchCondition(this.getCollectableSearchConditionFromSearchPanel(true)); result.setEntityName(this.getEntityName()); /** @todo set sorting column names */ return result; } public JComboBox getSearchFilterComboBox() { final SearchPanel sp = getSearchPanel(); if (sp == null) { return null; } return sp.cmbbxSearchFilter; } /** * @return the search filter (if any) selected in the combo box */ public final SearchFilter getSelectedSearchFilter() { return (SearchFilter) getSearchFilterComboBox().getSelectedItem(); } /** * selects the given search filter in the search filters combo box. * @param filter * @postcondition LangUtils.equals(this.getSelectedSearchFilter(), filter) */ public final void setSelectedSearchFilter(SearchFilter filter) { this.getSearchFilterComboBox().setSelectedItem(filter); } /** * selects the default filter (the first entry in the combobox). */ public void selectDefaultFilter() { if (this.getSearchFilterComboBox().getItemCount() > 0) { this.getSearchFilterComboBox().setSelectedIndex(0); } } protected void cmdSetCollectableSearchConditionAccordingToFilter() { if (!this.isSearchPanelAvailable()) { return; } UIUtils.runShortCommand(this.getTab(), new CommonRunnable() { @Override public void run() { try { final SearchFilter filterSelected = getSelectedSearchFilter(); // filterSelected may be null here as an ActionEvent is triggered by Swing even after // DefaultComboBoxModel.removeAllElements() is called. setCollectableSearchConditionInSearchPanel( filterSelected == null ? null : filterSelected.getSearchCondition()); if (filterSelected == null || filterSelected.isDefaultFilter()) { clearSearchCondition(); } if (filterSelected != null && filterSelected.getSearchDeleted() != null) { setSearchDeleted(filterSelected.getSearchDeleted()); } } catch (Exception ex) { Errors.getInstance().showExceptionDialog(getTab(), getSpringLocaleDelegate().getMessage("NuclosCollectController.12", "Suchbedingung kann nicht in der Suchmaske dargestellt werden."), ex); } } }); } public void setSearchDeleted(Integer iSearchDeleted) { //override in GenericObjectCollectController } public void cmdExecuteRuleByUser(MainFrameTab iFrame, final String sEntityName, Clct clct) { if (this.getCollectState().getInnerState() != CollectStateConstants.DETAILSMODE_VIEW) { throw new IllegalStateException("view mode"); } if (clct != null) { final SelectController controller = new SelectController(iFrame); UIUtils.runCommand(this.getTab(), new CommonRunnable() { @Override public void run() throws CommonBusinessException { final Collection<RuleVO> collRules = getUserRules(); final ChoiceList<RuleVO> ro = new ChoiceList<RuleVO>(); ro.set(collRules, new Comparator<RuleVO>() { @Override public int compare(RuleVO o1, RuleVO o2) { return o1.getRule().compareTo(o2.getRule()); } }); controller.setModel(ro); if (controller.run(getSpringLocaleDelegate().getMessage("NuclosCollectController.11", "Regeln ausf\u00fchren"))) { //execute the selected Rules final List<RuleVO> lstRuleToExecute = CollectionUtils .typecheck(controller.getSelectedObjects(), RuleVO.class); if (lstRuleToExecute != null && !lstRuleToExecute.isEmpty()) { try { executeBusinessRules(lstRuleToExecute, controller.getMySelectObjectsPanel().getSaveAfterExec().isSelected()); } catch (CommonBusinessException ex) { controller.setBlnExceptionOnWork(true); if (!handleSpecialException(ex)) throw ex; } } } } }); //refresh the current object if it has been saved if (controller.getMySelectObjectsPanel().getSaveAfterExec().isSelected() && !controller.getSelectedObjects().isEmpty() && !controller.isBlnExceptionOnWork()) { this.cmdRefreshCurrentCollectable(); } } } public void executeBusinessRules(List<RuleVO> lstRuleVO, boolean bSaveAfterRuleExecution) throws CommonBusinessException { //override in MasterDataCollectController and GenericObjectCollectController } /** * is entity of this controller transferable, that means that collectables * of this entity can be exported and imported. * * TODO: Make this protected again. */ @Override public boolean isTransferable() { Boolean bTransferable = false; String sEntityName = getEntityName(); if (SecurityCache.getInstance().isActionAllowed(Actions.ACTION_XML_EXPORT_IMPORT)) { if (Modules.getInstance().isModuleEntity(sEntityName)) { Object obj = Modules.getInstance().getModuleByEntityName(sEntityName).getField("importexport"); bTransferable = (obj != null) ? (Boolean) obj : false; } else { bTransferable = MasterDataDelegate.getInstance().getMetaData(sEntityName).getIsImportExport(); } } return bTransferable; } private static class MySelectObjectsPanel<T> extends DefaultSelectObjectsPanel<T> { private JCheckBox cbxSaveAfterRuleExecution; MySelectObjectsPanel() { } @Override protected void init() { super.init(); cbxSaveAfterRuleExecution = new JCheckBox(); cbxSaveAfterRuleExecution.setText(SpringLocaleDelegate.getInstance() .getMessage("NuclosCollectController.10", "Objekt nach Regelausf\u00fchrung speichern")); this.pnlMain.add(cbxSaveAfterRuleExecution, new GridBagConstraints(2, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); } JCheckBox getSaveAfterExec() { return cbxSaveAfterRuleExecution; } } /** * helper class for cmdExecuteRulesByUser */ private static class SelectController extends SelectObjectsController<RuleVO> { private boolean blnExceptionOnWork; public SelectController(Component parent) { super(parent, new MySelectObjectsPanel()); final MySelectObjectsPanel panel = (MySelectObjectsPanel) getPanel(); panel.btnUp.setEnabled(true); panel.btnDown.setEnabled(true); panel.btnUp.setVisible(true); panel.btnDown.setVisible(true); blnExceptionOnWork = false; } public boolean isBlnExceptionOnWork() { return blnExceptionOnWork; } public void setBlnExceptionOnWork(boolean blnExceptionOnWork) { this.blnExceptionOnWork = blnExceptionOnWork; } MySelectObjectsPanel getMySelectObjectsPanel() { return (MySelectObjectsPanel) getPanel(); } } @Override protected boolean isDetailsModeViewLoadingWithoutDependants() { return false; } /** * @return the user preferences node for this */ @Override public Preferences getPreferences() { return super.getPreferences(); } @Override public EntityPreferences getEntityPreferences() { getWorkspaceUtils().validatePreferences(super.getEntityPreferences()); return super.getEntityPreferences(); } @Override protected Clct findCollectableById(String sEntity, Object oId) throws CommonBusinessException { // TODO Auto-generated method stub return null; } @Override protected Clct findCollectableById(String sEntity, Object oId, Collection<EntityFieldMetaDataVO> fields) throws CommonBusinessException { return findCollectableById(sEntity, oId); } @Override protected Clct findCollectableByIdWithoutDependants(String sEntity, Object oId) throws CommonBusinessException { // TODO Auto-generated method stub return null; } @Override protected Clct updateCollectable(Clct clct, Object oAdditionalData) throws CommonBusinessException { // TODO Auto-generated method stub return null; } @Override protected Clct insertCollectable(Clct clctNew) throws CommonBusinessException { // TODO Auto-generated method stub return null; } @Override protected void deleteCollectable(Clct clct) throws CommonBusinessException { // TODO Auto-generated method stub } @Override protected String getEntityLabel() { // TODO Auto-generated method stub return null; } @Override public Clct newCollectable() { // TODO Auto-generated method stub return null; } public Collection<RuleVO> getUserRules() { return Collections.EMPTY_LIST; } @Override protected final void initTab() { super.initTab(); getTab().setTabStoreController(new NuclosCollectController.NuclosCollectTabStoreController(this)); } @Override public Pair<IconResolver, String> getIconAndResolver() { return Main.getInstance().getMainFrame().getEntityIconAndResolver(getEntityName()); } @Override public String getCustomUsage() { return null; } } // class NuclosCollectController