View Javadoc

1   // $Id: SimilarTypesView.java 169 2010-08-26 18:59:04Z agony $
2   /*
3    * xsAnalyzer - XML schema analyzing tool. Copyright (C) 2008 Michael Engelhardt
4    * 
5    * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
6    * License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
7    * version.
8    * 
9    * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
10   * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
11   * 
12   * You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
13   * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14   */
15  /**
16   * 
17   */
18  package de.mindcrimeilab.xsanalyzer;
19  
20  import java.awt.BorderLayout;
21  import java.beans.PropertyChangeEvent;
22  import java.beans.PropertyChangeListener;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.Map;
26  
27  import javax.swing.JComponent;
28  import javax.swing.JList;
29  import javax.swing.JPanel;
30  import javax.swing.JSplitPane;
31  import javax.swing.ListModel;
32  import javax.swing.ScrollPaneConstants;
33  import javax.swing.event.ListSelectionEvent;
34  import javax.swing.event.ListSelectionListener;
35  
36  import org.apache.xerces.xs.XSObject;
37  import org.apache.xerces.xs.XSObjectList;
38  import org.springframework.binding.value.ValueModel;
39  import org.springframework.binding.value.support.ValueHolder;
40  import org.springframework.context.ApplicationEvent;
41  import org.springframework.context.ApplicationListener;
42  import org.springframework.richclient.application.PageComponentContext;
43  import org.springframework.richclient.application.support.AbstractView;
44  import org.springframework.richclient.command.CommandGroup;
45  import org.springframework.richclient.command.GuardedActionCommandExecutor;
46  import org.springframework.richclient.command.support.AbstractActionCommandExecutor;
47  import org.springframework.richclient.command.support.GlobalCommandIds;
48  import org.springframework.richclient.factory.ComponentFactory;
49  import org.springframework.richclient.layout.GridBagLayoutBuilder;
50  import org.springframework.richclient.list.FilteredListModel;
51  import org.springframework.richclient.list.ListSelectionValueModelAdapter;
52  import org.springframework.richclient.util.PopupMenuMouseListener;
53  
54  import de.mindcrimeilab.util.SimilarTypeEntryAccessor;
55  import de.mindcrimeilab.xsanalyzer.actions.AbstractXSObjectCommand;
56  import de.mindcrimeilab.xsanalyzer.actions.TypeHierarchyCommand;
57  import de.mindcrimeilab.xsanalyzer.actions.TypeInspectionCommand;
58  import de.mindcrimeilab.xsanalyzer.actions.XsAnalyzerApplicationEvent;
59  import de.mindcrimeilab.xsanalyzer.actions.XsElementPropertiesExecutor;
60  import de.mindcrimeilab.xsanalyzer.model.JListSelectionValueModelAdapter;
61  import de.mindcrimeilab.xsanalyzer.model.SimilarTypeListModelEntry;
62  import de.mindcrimeilab.xsanalyzer.model.SimilarTypeListModelFactory;
63  import de.mindcrimeilab.xsanalyzer.model.SimilarTypesListModelAdapter;
64  import de.mindcrimeilab.xsanalyzer.model.XsAnalyzerApplicationModel;
65  import de.mindcrimeilab.xsanalyzer.rules.constraints.SchemaTypeConstraint;
66  import de.mindcrimeilab.xsanalyzer.ui.MasterListDetailList;
67  import de.mindcrimeilab.xsanalyzer.ui.filter.FilterToolbarFactory;
68  import de.mindcrimeilab.xsanalyzer.ui.renderer.SchemaElementsRenderer;
69  import de.mindcrimeilab.xsanalyzer.ui.renderer.SimilarTypeRenderer;
70  
71  /**
72   * User interface to the discovered similar types in the schema.
73   * 
74   * @author Michael Engelhardt<me@mindcrime-ilab.de>
75   * @author $Author: agony $
76   * @version $Revision: 169 $
77   * 
78   */
79  public class SimilarTypesView extends AbstractView implements ApplicationListener {
80  
81      private final MasterListDetailList masterDetailList;
82  
83      private XsAnalyzerApplicationModel model;
84  
85      private final ValueModel numSimilarTypesSchema = new ValueHolder(0);
86  
87      private final ValueModel numSimilarTypes = new ValueHolder(0);
88  
89      private final XsElementPropertiesExecutor xsElementPropertiesExecutor = new XsElementPropertiesExecutor();
90  
91      private final GuardedActionCommandExecutor propertiesExecutor = new PropertiesExecutor();
92  
93      private final AbstractXSObjectCommand typesListTypeHierarchyCommand;
94  
95      private final AbstractXSObjectCommand similarTypesTypeHierarchyCommand;
96  
97      private final AbstractXSObjectCommand typesListTypeInspectionCommand;
98  
99      private final AbstractXSObjectCommand similarTypesInspectionCommand;
100 
101     private final SchemaTypeConstraint elementTypeConstraint;
102 
103     public SimilarTypesView() {
104         final SimilarTypeEntryAccessor accessor = new SimilarTypeEntryAccessor();
105 
106         similarTypesTypeHierarchyCommand = new TypeHierarchyCommand();
107         similarTypesTypeHierarchyCommand.setAccessor(accessor);
108 
109         similarTypesInspectionCommand = new TypeInspectionCommand();
110         similarTypesInspectionCommand.setAccessor(accessor);
111 
112         typesListTypeHierarchyCommand = new TypeHierarchyCommand();
113         typesListTypeInspectionCommand = new TypeInspectionCommand();
114 
115         elementTypeConstraint = new SchemaTypeConstraint(accessor);
116 
117         masterDetailList = new MasterListDetailList();
118         masterDetailList.setListModelFactory(new SimilarTypeListModelFactory(elementTypeConstraint));
119 
120         masterDetailList.addPropertyChangeListener(MasterListDetailList.PC_MASTERLIST_LISTMODEL, new PropertyChangeListener() {
121 
122             @Override
123             public void propertyChange(PropertyChangeEvent evt) {
124                 logger.debug("Adjusting commands to new model " + evt.getPropertyName());
125                 final ListModel listModel = (ListModel) evt.getNewValue();
126                 final ValueModel selectionModel = new ListSelectionValueModelAdapter(masterDetailList.getMasterList().getSelectionModel());
127                 final ValueModel vModel = new JListSelectionValueModelAdapter(listModel, (ListSelectionValueModelAdapter) selectionModel);
128                 similarTypesTypeHierarchyCommand.setValueModel(vModel);
129                 similarTypesInspectionCommand.setValueModel(vModel);
130                 numSimilarTypesSchema.setValue(listModel.getSize());
131             }
132         });
133 
134         masterDetailList.addPropertyChangeListener(MasterListDetailList.PC_DETAILLIST_LISTMODEL, new PropertyChangeListener() {
135 
136             @Override
137             public void propertyChange(PropertyChangeEvent evt) {
138                 logger.debug("Adjusting commands to new model " + evt.getPropertyName());
139                 final ListModel listModel = (ListModel) evt.getNewValue();
140                 final ValueModel selectionModel = new ListSelectionValueModelAdapter(masterDetailList.getDetailList().getSelectionModel());
141                 final ValueModel vModel = new JListSelectionValueModelAdapter(listModel, (ListSelectionValueModelAdapter) selectionModel);
142                 typesListTypeHierarchyCommand.setValueModel(vModel);
143                 typesListTypeInspectionCommand.setValueModel(vModel);
144                 numSimilarTypes.setValue(listModel.getSize());
145             }
146         });
147     }
148 
149     @Override
150     protected void registerLocalCommandExecutors(PageComponentContext context) {
151         context.register(GlobalCommandIds.PROPERTIES, propertiesExecutor);
152     }
153 
154     /*
155      * (non-Javadoc)
156      * 
157      * @see org.springframework.richclient.application.support.AbstractView#createControl()
158      */
159     @Override
160     protected JComponent createControl() {
161         final ComponentFactory cf = getComponentFactory();
162 
163         final JList masterList = masterDetailList.getMasterList();
164         final JList detailList = masterDetailList.getDetailList();
165         detailList.setCellRenderer(new SchemaElementsRenderer());
166         masterList.setCellRenderer(new SimilarTypeRenderer());
167 
168         // build master view
169         final GridBagLayoutBuilder typeListPanelBuilder = new GridBagLayoutBuilder();
170         typeListPanelBuilder.append(cf.createLabel("similarTypesView.typeList.label", new ValueModel[] { numSimilarTypesSchema})).nextLine();
171         typeListPanelBuilder.append(cf.createScrollPane(masterList, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), 1, 1, true, true);
172 
173         final CommandGroup group = getWindowCommandManager().createCommandGroup("similarTypesCommandGroup", new Object[] { similarTypesTypeHierarchyCommand, similarTypesInspectionCommand, "separator", GlobalCommandIds.PROPERTIES});
174         masterList.addMouseListener(new PopupMenuMouseListener(group.createPopupMenu()));
175 
176         masterList.addListSelectionListener(new ListSelectionListener() {
177 
178             @Override
179             public void valueChanged(ListSelectionEvent evt) {
180                 Map<String, XSObject> parameters = new HashMap<String, XSObject>();
181                 final SimilarTypeListModelEntry similarTypeListModelEntry = (SimilarTypeListModelEntry) masterList.getSelectedValue();
182                 if (null == similarTypeListModelEntry) return;
183                 parameters.put(XsElementPropertiesExecutor.OBJECT, similarTypeListModelEntry.getType());
184                 xsElementPropertiesExecutor.execute(parameters);
185             }
186         });
187 
188         // build client view
189         final GridBagLayoutBuilder similarTypesListPanelBuilder = new GridBagLayoutBuilder();
190         similarTypesListPanelBuilder.append(cf.createLabel("similarTypesView.similarTypeList.label", new ValueModel[] { numSimilarTypes})).nextLine();
191         similarTypesListPanelBuilder.append(cf.createScrollPane(detailList, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), 1, 1, true, true);
192 
193         final CommandGroup detailListGroup = getWindowCommandManager().createCommandGroup("typeListCommandGroup", new Object[] { typesListTypeHierarchyCommand, typesListTypeInspectionCommand, "separator", GlobalCommandIds.PROPERTIES});
194         detailList.addMouseListener(new PopupMenuMouseListener(detailListGroup.createPopupMenu()));
195 
196         detailList.addListSelectionListener(new ListSelectionListener() {
197 
198             @Override
199             public void valueChanged(ListSelectionEvent evt) {
200                 Map<String, XSObject> parameters = new HashMap<String, XSObject>();
201                 parameters.put(XsElementPropertiesExecutor.OBJECT, (XSObject) detailList.getSelectedValue());
202                 xsElementPropertiesExecutor.execute(parameters);
203             }
204         });
205 
206         // build main component
207         JSplitPane jspSimilarTypes = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
208         jspSimilarTypes.setDividerLocation(0.66f);
209         jspSimilarTypes.setTopComponent(typeListPanelBuilder.getPanel());
210         jspSimilarTypes.setBottomComponent(similarTypesListPanelBuilder.getPanel());
211 
212         JPanel jpSimilarTypes = cf.createPanel(new BorderLayout());
213         jpSimilarTypes.add(jspSimilarTypes, BorderLayout.CENTER);
214         jpSimilarTypes.add(FilterToolbarFactory.createFilterToolBar(elementTypeConstraint), BorderLayout.NORTH);
215 
216         return jpSimilarTypes;
217     }
218 
219     /**
220      * @return the model
221      */
222     public XsAnalyzerApplicationModel getModel() {
223         return model;
224     }
225 
226     /**
227      * @param model
228      *            the model to set
229      */
230     public void setModel(XsAnalyzerApplicationModel model) {
231         this.model = model;
232         updateModel();
233     }
234 
235     private void updateModel() {
236         if (null != model) {
237             update(model.getSimilarTypes());
238         }
239     }
240 
241     /**
242      * @param similarTypes
243      */
244     private void update(final Map<String, XSObjectList> similarTypes) {
245         final SimilarTypesListModelAdapter similarTypesListModelAdapter = new SimilarTypesListModelAdapter(similarTypes);
246         final FilteredListModel filteredModel = new FilteredListModel(similarTypesListModelAdapter, elementTypeConstraint);
247         masterDetailList.setMasterListModel(filteredModel);
248         numSimilarTypesSchema.setValue(similarTypesListModelAdapter.getSize());
249     }
250 
251     private void invalidate() {
252         update(Collections.<String, XSObjectList> emptyMap());
253     }
254 
255     @Override
256     public void onApplicationEvent(ApplicationEvent event) {
257         if (event instanceof XsAnalyzerApplicationEvent) {
258             switch (((XsAnalyzerApplicationEvent) event).getEventType()) {
259                 case SIMILAR_TYPES:
260                     XsAnalyzerApplicationModel appmodel = (XsAnalyzerApplicationModel) getApplicationContext().getBean("applicationModel");
261                     setModel(appmodel);
262                     break;
263                 case OPEN:
264                     invalidate();
265                     break;
266             }
267         }
268 
269     }
270 
271     private class PropertiesExecutor extends AbstractActionCommandExecutor {
272 
273         @Override
274         public boolean isEnabled() {
275             return true;
276         }
277 
278         @Override
279         public void execute() {
280             SimilarTypeListModelEntry selectedValue = (SimilarTypeListModelEntry) masterDetailList.getMasterList().getSelectedValue();
281             Map<String, XSObject> parameters = new HashMap<String, XSObject>();
282             parameters.put(XsElementPropertiesExecutor.OBJECT, selectedValue.getType());
283             xsElementPropertiesExecutor.execute(parameters);
284         }
285     }
286 }