NXvalidate  1
 All Classes Namespaces Files Functions Variables
NXSnode.java
Go to the documentation of this file.
1 /* NeXus - Neutron & X-ray Common Data Format
2  *
3  * NeXus file validation GUI tool.
4  *
5  * Copyright (C) 2010 Nexus Team
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  *
21  * For further information, see <http://www.nexusformat.org/>
22  *
23  * NXSnode.java
24  *
25  */
26 package org.nexusformat.nxvalidate;
27 
28 import java.util.ArrayList;
29 import java.util.Vector;
30 
31 import javax.swing.event.TreeModelListener;
32 import javax.swing.tree.TreeModel;
33 import javax.swing.tree.TreePath;
34 
35 import org.w3c.dom.NamedNodeMap;
36 import org.w3c.dom.Node;
37 import org.w3c.dom.NodeList;
38 
39 class NXSnode extends AbstractNXSnode implements TreeModel {
40 
41  private static final String PADDING = " ";
42  private static final String NXROOT = "NXroot";
43  private static final String TYPE = "NAPItype";
44  private static final String LINK = "NAPIlink";
45  private static final String SDS = "SDS";
46  private static final Logger LOG = Logger.getInstance();
47  private String name;
48  private String nxclass;
49  private ArrayList<AbstractNXSnode> children;
50  private ArrayList<SVRLitem> svrl;
51 
52  NXSnode() {
53  super(NXROOT);
54  this.nxclass = "";
55  this.children = new ArrayList<AbstractNXSnode>();
56  this.svrl = new ArrayList<SVRLitem>();
57  }
58 
59  NXSnode(final Node node) {
60  this();
61  this.nxclass = node.getNodeName();
62  this.setAttrs(node.getAttributes());
63 
64  NodeList nodes = node.getChildNodes();
65  int size = nodes.getLength();
66  for (int i = 0; i < size; i++) {
67  this.addChild(nodes.item(i));
68  }
69  }
70 
71  ArrayList<SVRLitem> addSVRL(final Node svrl) {
72  // generate a list of xml error nodes
73  ArrayList<Node> errors = new ArrayList<Node>();
74  addSVRL(svrl, errors);
75 
76  // convert it to java classes
77  ArrayList<SVRLitem> items = new ArrayList<SVRLitem>();
78  for (Node node : errors) {
79  items.add(new SVRLitem(node));
80  }
81 
82  // find the appropriate nodes to attach it to
83  NXSnode nxsnode;
84  for (SVRLitem item : items) {
85  nxsnode = getNode(this, item.getLocationArray(), 1);
86  nxsnode.svrl.add(item);
87  }
88 
89  return items;
90  }
91 
92  private static NXSnode getNode(NXSnode parent, ArrayList<String> location,
93  int depth) {
94  // chop up this part of the path to be useful
95  if (location.size() <= depth) {
96  return parent;
97  }
98  String partPath = location.get(depth);
99  int left = partPath.indexOf("[");
100  int right = partPath.indexOf("]", left);
101  String name = partPath.substring(0, left);
102  int index = Integer.parseInt(partPath.substring(left + 1, right)) - 1;
103  LOG.debug("Looking for " + name + "[" + index + "]");
104 
105  // get the options - only works with NXSnodes
106  ArrayList<NXSnode> choices = new ArrayList<NXSnode>();
107  NXSnode temp;
108  for (AbstractNXSnode child : parent.children) {
109  if (child instanceof NXSnode) {
110  temp = (NXSnode) child;
111  if (equals(temp.getType(), name)) {
112  choices.add(temp);
113  } else if (equals(temp.getName(), name)) {
114  choices.add(temp);
115  }
116  }
117  }
118 
119  // pick which one to return
120  int numChoice = choices.size();
121  LOG.debug("Found " + numChoice + " options");
122  if ((numChoice <= 0) || (numChoice < index)) {
123  return parent;
124  }
125  if (depth >= location.size()) {
126  return choices.get(index);
127  } else {
128  return getNode(choices.get(index), location, depth + 1);
129  }
130  }
131 
132  private static boolean equals(final String left, final String right) {
133  if (left == null) {
134  return false;
135  }
136  if (right == null) {
137  return false;
138  }
139  return left.equals(right);
140  }
141 
142  private static void addSVRL(final Node node, final ArrayList<Node> errors) {
143  if (SVRLitem.hasLocation(node)) {
144  errors.add(node);
145  return;
146  }
147  NodeList nodes = node.getChildNodes();
148  int size = nodes.getLength();
149  for (int i = 0; i < size; i++) {
150  addSVRL(nodes.item(i), errors);
151  }
152  }
153 
154  private void setAttrs(final NamedNodeMap attrs) {
155  if (attrs == null) {
156  return;
157  }
158  int size = attrs.getLength();
159  Node attr;
160  for (int i = 0; i < size; i++) {
161  attr = attrs.item(i);
162  this.setAttr(attr.getNodeName(), attr.getNodeValue());
163  }
164  }
165 
166  void setAttr(final String name, final String value) {
167  if (name.equals("name")) {
168  this.setName(value);
169  return;
170  } else if (name.equals(TYPE)) {
171  this.setName(this.nxclass);
172  this.nxclass = SDS;
173  return;
174  }
175  this.children.add(0, new Attribute(name, value));
176  }
177 
178  private void addChild(final Node node) {
179  if (node == null) {
180  return;
181  }
182  int type = node.getNodeType();
183  if (type != Node.ELEMENT_NODE) {
184  return;
185  }
186  this.children.add(new NXSnode(node));
187  }
188 
189  String getType() {
190  return this.nxclass;
191  }
192 
193  boolean hasError() {
194  return (this.svrl.size() > 0);
195  }
196 
197  private String getAttrValue(final String name) {
198  int size = this.children.size();
199  AbstractNXSnode node;
200  for (int i = 0; i < size; i++) {
201  node = this.children.get(i);
202  if (node instanceof NXSnode) {
203  return "";
204  } else if (this.children.get(i).getName().equals(name)) {
205  return ((Attribute) node).getValue();
206  }
207  }
208  return "";
209  }
210 
211  public String toString() {
212  String result;
213  if (NXROOT.equals(this.getName()) || NXROOT.equals(this.nxclass)) {
214  result = NXROOT;
215  } else if (LINK.equals(this.getName())) {
216  result = this.getName() + ":target=" + this.getAttrValue("target");
217  } else if (SDS.equals(this.nxclass)) {
218  result = this.getName() + ":" + TYPE + "=" + this.getAttrValue(TYPE);
219  } else {
220  result = this.getName() + ":" + this.nxclass;
221  }
222  if (this.hasError()) {
223  return result + "*";
224  } else {
225  return result;
226  }
227  }
228 
229  public void printTree() {
230  this.printTree("");
231  }
232 
233  private void printTree(String padding) {
234  System.out.println(padding + this.toString());
235  padding += PADDING;
236  for (AbstractNXSnode node : this.children) {
237  if (node instanceof NXSnode) // don't bother with attributes
238  {
239  ((NXSnode) node).printTree(padding);
240  }
241  }
242  }
243 
244  public boolean equals(final Object other) {
245  // do the simple checks
246  if (this == other) {
247  return true;
248  }
249  if (other == null) {
250  return false;
251  }
252  if (!(other instanceof NXSnode)) {
253  return false;
254  }
255 
256  // cast and do deep comparison
257  NXSnode temp = (NXSnode) other;
258  if (!this.getName().equals(temp.getName())) {
259  return false;
260  }
261  if (!this.nxclass.equals(temp.nxclass)) {
262  return false;
263  }
264  if (!this.children.equals(temp.children)) {
265  return false;
266  }
267  if (!this.svrl.equals(temp.svrl)) {
268  return false;
269  }
270 
271  // this far must be ok
272  return true;
273  }
274 
275  private static NXSnode toNXSnode(final Object object) {
276  if (object == null) {
277  throw new Error("Cannot convert null object to NXSnode");
278  }
279  if (!(object instanceof NXSnode)) {
280  throw new Error("Cannot convert \"" + object + "\" to NXSnode");
281  }
282  return (NXSnode) object;
283  }
284 
285  // ---------------- TreeModel requirements
286  @Override
287  public void addTreeModelListener(TreeModelListener l) {
288  // TODO Auto-generated method stub
289  }
290 
291  public Object getChild(Object parent, int index) {
292  if (parent instanceof NXSnode) {
293  return ((NXSnode) parent).children.get(index);
294  } else {
295  return null;
296  }
297  }
298 
299  public int getChildCount(Object parent) {
300  NXSnode temp = toNXSnode(parent);
301  return temp.children.size();
302  }
303 
304  public int getIndexOfChild(Object parent, Object child) {
305  if (parent == null) {
306  return -1;
307  }
308  if (child == null) {
309  return -1;
310  }
311  NXSnode myParent = toNXSnode(parent);
312  if (child instanceof AbstractNXSnode) {
313  return myParent.children.indexOf((AbstractNXSnode) child);
314  } else {
315  return -1;
316  }
317  }
318 
319  public Object getRoot() {
320  return this;
321  }
322 
323  public boolean isLeaf(final Object node) {
324  if (node instanceof NXSnode) {
325  return (((NXSnode) node).children.size() <= 0);
326  } else {
327  return true;
328  }
329  }
330 
331  @Override
332  public void removeTreeModelListener(TreeModelListener l) {
333  // TODO Auto-generated method stub
334  }
335 
336  @Override
337  public void valueForPathChanged(TreePath path, Object newValue) {
338  // TODO Auto-generated method stub
339  }
340 }