View Javadoc

1   /*
2    * Created on Mar 20, 2005. Copyright 1999-2006 Faculty of Mathematics, Physics
3    * and Informatics, Comenius University, Bratislava. This file is protected by
4    * the Mozilla Public License version 1.1 (the "License"); you may not use this
5    * file except in compliance with the License. You may obtain a copy of the
6    * License at http://euromath2.sourceforge.net/license.html Unless required by
7    * applicable law or agreed to in writing, software distributed under the
8    * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
9    * OF ANY KIND, either express or implied. See the License for the specific
10   * language governing permissions and limitations under the License.
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  		// create first page
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 	 * (non-Javadoc)
105 	 * @see sk.uniba.euromath.editor.wizards.IWizard#canFinish()
106 	 */
107 	public boolean canFinish() {
108 		if (npqPage != null)
109 			return !npqPage.hasErrors();
110 		// we are on first page. we can finish only if this page does not
111 		// introduce new namespaces
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 	 * (non-Javadoc)
125 	 * @see sk.uniba.euromath.editor.wizards.IWizard#hasNext()
126 	 */
127 	public boolean hasNext() {
128 		if (npqPage != null)
129 			return false;
130 		// we are on first page. we can finish only if this page does not
131 		// introduce new namespaces
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 	 * (non-Javadoc)
145 	 * @see sk.uniba.euromath.editor.wizards.IWizard#hasPrevious()
146 	 */
147 	public boolean hasPrevious() {
148 		return npqPage != null;
149 	}
150 	/*
151 	 * (non-Javadoc)
152 	 * @see sk.uniba.euromath.editor.wizards.IWizard#next()
153 	 */
154 	public BaseWizardPage next() {
155 		if (!hasNext())
156 			throw new NoSuchElementException();
157 		assert npqPage == null;
158 		// we are on the first page, second page is requested.
159 		assert !canFinish();
160 		// ok, prefixes must be queried. Create wizard page for that.
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 	 * (non-Javadoc)
168 	 * @see sk.uniba.euromath.editor.wizards.IWizard#current()
169 	 */
170 	public BaseWizardPage current() {
171 		if (npqPage != null)
172 			return npqPage;
173 		return calPage;
174 	}
175 	/*
176 	 * (non-Javadoc)
177 	 * @see sk.uniba.euromath.editor.wizards.IWizard#dispose()
178 	 */
179 	public void dispose() {
180 		// do nothing
181 	}
182 	/*
183 	 * (non-Javadoc)
184 	 * @see sk.uniba.euromath.editor.wizards.IWizard#getName()
185 	 */
186 	public String getName() {
187 		return Messages.getString("CREATE_ATTRIBUTES"); //$NON-NLS-1$
188 	}
189 	/*
190 	 * (non-Javadoc)
191 	 * @see sk.uniba.euromath.editor.wizards.IWizard#getTitleBarColor()
192 	 */
193 	public RGB getTitleBarColor() {
194 		return null;
195 	}
196 	/*
197 	 * (non-Javadoc)
198 	 * @see sk.uniba.euromath.editor.wizards.IWizard#previous()
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 	 * (non-Javadoc)
209 	 * @see sk.uniba.euromath.editor.wizards.IWizard#performCancel()
210 	 */
211 	public boolean performCancel() {
212 		return true;
213 	}
214 	/*
215 	 * (non-Javadoc)
216 	 * @see sk.uniba.euromath.editor.wizards.IWizard#performFinish()
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"); //$NON-NLS-1$
245 		final List<String> newAttrValues = calPage.getWidget().getValues();
246 		if ((newAttrValues == null)
247 				|| (calPage.getWidget().getMessages() != null))
248 			throw new IllegalStateException("Errors in page"); //$NON-NLS-1$
249 		// create all attributes selected in created page.
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")); //$NON-NLS-1$
281 		if (dlg.open() != Window.OK)
282 			return;
283 		// create attributes
284 		xmlAccess.getModifier().startModify();
285 		wizard.createAttributes(element, xmlAccess.getModifier());
286 		xmlAccess.getModifier().endModify();
287 	}
288 }