1
2
3
4
5
6
7
8
9
10
11
12 package sk.uniba.euromath.editor.wizards.document;
13 import java.util.List;
14 import java.util.NoSuchElementException;
15 import java.util.Set;
16 import javax.xml.namespace.QName;
17 import org.apache.commons.lang.StringUtils;
18 import org.eclipse.jface.window.Window;
19 import org.eclipse.swt.graphics.RGB;
20 import org.eclipse.swt.widgets.Shell;
21 import org.w3c.dom.Attr;
22 import org.w3c.dom.Element;
23 import sk.baka.ikslibs.DOMUtils;
24 import sk.baka.xml.gene.ExportException;
25 import sk.uniba.euromath.document.DocumentModifier;
26 import sk.uniba.euromath.document.NamespaceManager;
27 import sk.uniba.euromath.document.XMLAccess;
28 import sk.uniba.euromath.document.schema.AttributeListRule;
29 import sk.uniba.euromath.editor.lang.Messages;
30 import sk.uniba.euromath.editor.wizards.BaseWizardPage;
31 import sk.uniba.euromath.editor.wizards.IWizard;
32 import sk.uniba.euromath.editor.wizards.WizardDialog;
33 /***
34 * <p>
35 * Manages the process of creating new attributes into newly created element.
36 * Attributes themselves are not created, their names and values are returned
37 * instead. Prefixes for new namespaces are queried.
38 * </p>
39 * @author Martin Vysny
40 */
41 public class CreateAttributeListWizard implements IWizard {
42 /***
43 * First wizard page. Never <code>null</code>.
44 */
45 public final CreateAttributeListWizardPage calPage;
46 /***
47 * Second wizard page. <code>null</code> when wizard is on the first page.
48 */
49 private NewPrefixesQueryWizardPage npqPage;
50 /***
51 * Returns second wizard page. <code>null</code> when wizard is on the
52 * first page.
53 * @return second wizard page. <code>null</code> when wizard is on the
54 * first page.
55 */
56 public NewPrefixesQueryWizardPage getNpqPage() {
57 return npqPage;
58 }
59 /***
60 * The document instance.
61 */
62 public final XMLAccess xmlAccess;
63 /***
64 * Constructor.
65 * @param listRules the list of lists of attribute. Exactly one list will be
66 * chosen.
67 * @param parentName the name of the parent element. Used only to display
68 * the name on the shell.
69 * @param xmlAccess the xml document instance.
70 * @param currentManager the current manager. It won't get modified. If new
71 * prefixes needs to be registered, they are registered in a separate
72 * namespace manager, built on demand by the <code>newNsManager()</code>.
73 */
74 public CreateAttributeListWizard(List<AttributeListRule> listRules,
75 String parentName, XMLAccess xmlAccess,
76 NamespaceManager currentManager) {
77 super();
78 this.currentManager = currentManager;
79 this.xmlAccess = xmlAccess;
80
81 calPage = new CreateAttributeListWizardPage(listRules, parentName,
82 xmlAccess, currentManager);
83 }
84 /***
85 * Current namespace manager.
86 */
87 protected final NamespaceManager currentManager;
88 /***
89 * Creates new namespace manager, with new namespace-prefix mappings. If no
90 * new mappings are defined, function simply returns old namespace manager.
91 * @return new namespace manager, or instance given to the object
92 * constructor if no new namespaces are introduced.
93 * @throws IllegalArgumentException if the page contains errors thus some
94 * prefixes cannot be registered.
95 * @throws IllegalStateException if the page contains errors thus some
96 * prefixes cannot be registered.
97 */
98 public NamespaceManager newNsManager() {
99 if (npqPage == null)
100 return currentManager;
101 return npqPage.npq.newUpdatedManager();
102 }
103
104
105
106
107 public boolean canFinish() {
108 if (npqPage != null)
109 return !npqPage.hasErrors();
110
111
112 if (calPage.hasErrors())
113 return false;
114 final List<QName> newAttrNames = calPage.getWidget().getNames();
115 final Set<String> allNamespaces = currentManager.getAllNamespaces();
116 for (final QName qname : newAttrNames) {
117 if ((!StringUtils.isEmpty(qname.getNamespaceURI()))
118 && !allNamespaces.contains(qname.getNamespaceURI()))
119 return false;
120 }
121 return true;
122 }
123
124
125
126
127 public boolean hasNext() {
128 if (npqPage != null)
129 return false;
130
131
132 if (calPage.hasErrors())
133 return false;
134 final List<QName> newAttrNames = calPage.getWidget().getNames();
135 final Set<String> allNamespaces = currentManager.getAllNamespaces();
136 for (final QName qname : newAttrNames) {
137 if ((!StringUtils.isEmpty(qname.getNamespaceURI()))
138 && !allNamespaces.contains(qname.getNamespaceURI()))
139 return true;
140 }
141 return false;
142 }
143
144
145
146
147 public boolean hasPrevious() {
148 return npqPage != null;
149 }
150
151
152
153
154 public BaseWizardPage next() {
155 if (!hasNext())
156 throw new NoSuchElementException();
157 assert npqPage == null;
158
159 assert !canFinish();
160
161 final Set<String> namespaces = calPage.getWidget().getAllNamespaces();
162 namespaces.removeAll(currentManager.getAllNamespaces());
163 npqPage = new NewPrefixesQueryWizardPage(namespaces, currentManager);
164 return npqPage;
165 }
166
167
168
169
170 public BaseWizardPage current() {
171 if (npqPage != null)
172 return npqPage;
173 return calPage;
174 }
175
176
177
178
179 public void dispose() {
180
181 }
182
183
184
185
186 public String getName() {
187 return Messages.getString("CREATE_ATTRIBUTES");
188 }
189
190
191
192
193 public RGB getTitleBarColor() {
194 return null;
195 }
196
197
198
199
200 public BaseWizardPage previous() {
201 if (!hasPrevious())
202 throw new NoSuchElementException();
203 assert npqPage != null;
204 npqPage = null;
205 return calPage;
206 }
207
208
209
210
211 public boolean performCancel() {
212 return true;
213 }
214
215
216
217
218 public boolean performFinish() {
219 return true;
220 }
221 /***
222 * Returns qnames of new attributes, with appropriate prefixes when needed.
223 * @return qnames of new attributes. <code>null</code> if error occurs.
224 */
225 public List<QName> getNames() {
226 final List<QName> qnames = calPage.getWidget().getNames();
227 if (npqPage == null)
228 return qnames;
229 if (qnames == null)
230 return null;
231 return npqPage.npq.setPrefixes(qnames);
232 }
233 /***
234 * Creates all selected attributes with their values. Function fails if
235 * there are errors on the page.
236 * @param e create attributes here.
237 * @param modifier if not <code>null</code> then changes are written using
238 * document modifier. Otherwise, they are written directly to the element.
239 * @throws IllegalStateException if there are still errors on the page.
240 */
241 public void createAttributes(Element e, DocumentModifier modifier) {
242 final List<QName> newAttrs = getNames();
243 if (newAttrs == null)
244 throw new IllegalStateException("Errors in page");
245 final List<String> newAttrValues = calPage.getWidget().getValues();
246 if ((newAttrValues == null)
247 || (calPage.getWidget().getMessages() != null))
248 throw new IllegalStateException("Errors in page");
249
250 for (int i = 0; i < newAttrs.size(); i++) {
251 final QName qname = newAttrs.get(i);
252 final String value = newAttrValues.get(i);
253 if (modifier == null) {
254 final Attr attr = xmlAccess.getDocument().createAttributeNS(
255 qname.getNamespaceURI(), DOMUtils.printQName(qname));
256 attr.setValue(value);
257 e.setAttributeNodeNS(attr);
258 } else {
259 modifier.createAttribute(e, qname, value);
260 }
261 }
262 }
263 /***
264 * Executes the wizard. When the wizard finishes the attributes are created
265 * succesfully, or nothing is done if the operation is cancelled by the
266 * user.
267 * @param parent the parent window. Should not be <code>null</code>.
268 * @param listRules the rules describing creatable attributes.
269 * @param element where to create the attributes.
270 * @param xmlAccess the document instance.
271 * @throws ExportException if modification finalizer fails.
272 */
273 public static void execute(Shell parent, List<AttributeListRule> listRules,
274 Element element, XMLAccess xmlAccess) throws ExportException {
275 xmlAccess.getContent().checkNode(element);
276 final CreateAttributeListWizard wizard = new CreateAttributeListWizard(
277 listRules, DOMUtils.printQName(element), xmlAccess, xmlAccess
278 .getNsManager());
279 final WizardDialog dlg = new WizardDialog(parent, wizard, Messages
280 .getString("CREATE_ATTRIBUTES"));
281 if (dlg.open() != Window.OK)
282 return;
283
284 xmlAccess.getModifier().startModify();
285 wizard.createAttributes(element, xmlAccess.getModifier());
286 xmlAccess.getModifier().endModify();
287 }
288 }