Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
Asset.java
1 
20 package net.squiz.matrix.core;
21 
22 import net.squiz.matrix.matrixtree.*;
23 import net.squiz.matrix.debug.*;
24 import javax.swing.tree.*;
25 import org.w3c.dom.*;
26 import java.beans.*;
27 import java.util.*;
28 import java.awt.Color;
29 import java.io.*;
30 
37 public class Asset implements MatrixConstants, Serializable {
38 
39  protected final String id;
40  protected String initName = "";
41  private AssetType type;
42  private int status;
43  private boolean accessible;
44  private String url = "";
45  private String webPath = "";
46  private boolean childrenLoaded = false;
47  private int numKids = 0;
48  private int totalKidsLoaded = 0;
49  protected Map nodes = null;
50  private int sort_order = 0;
51 
52  //{{{ Public Methods
53 
54  public Asset(String id) {
55  this.id = id;
56  //nodes = new ArrayList();
57  nodes = new HashMap();
58  }
59 
69  public Asset(Element assetElement, MatrixTreeNode parent, int index) {
70  this(MatrixToolkit.rawUrlDecode(assetElement.getAttribute("assetid")));
71  String linkid = processAssetXML(assetElement, true);
72  createNode(linkid, getLinkType(assetElement), parent, index);
73  // we need to tell the new node what its link type is
74  setLinkType(assetElement, linkid);
75  }
76 
77  public void setTotalKidsLoaded(int kidsLoaded) {
78  this.totalKidsLoaded = kidsLoaded;
79  }
80 
81  public int getTotalKidsLoaded() {
82  return totalKidsLoaded;
83  }
84 
85  public String toString() {
86  return "[" + id + "]";
87  }
88 
93  public String getId() {
94  return id;
95  }
96 
101  public String getName(String linkid) {
102  MatrixTreeNode node = getNode(linkid);
103  if (node == null) {
104  return "";
105  }
106  return node.getName();
107  }
108 
109  public boolean setName(String name, String linkid) {
110  if (linkid.equals("")) {
111  Iterator nodeIterator = getTreeNodes();
112  while (nodeIterator.hasNext()) {
113  MatrixTreeNode node = (MatrixTreeNode) nodeIterator.next();
114  if (node != null) {
115  node.setName(name);
116  return true;
117  }
118  }
119  }
120 
121  MatrixTreeNode node = getNode(linkid);
122  if (node != null) {
123  String nodeName = node.getName();
124  if (nodeName != null) {
125  if (nodeName.equals(name)) {
126  return false;
127  }
128  }
129  node.setName(name);
130  } else {
131  return false;
132  }
133  return true;
134  }
135 
136  public void addNode(MatrixTreeNode node, String linkid) {
137  nodes.put(linkid, node);
138  }
139 
140  public MatrixTreeNode getNode(String linkid) {
141  if (nodes.containsKey(linkid)) {
142  return (MatrixTreeNode)nodes.get(linkid);
143  }
144  return null;
145  }
146 
151  public String[] getLinkIds() {
152  String[] linkIds = new String[nodes.size()];
153  Iterator nodeIterator = getTreeNodes();
154  int i = 0;
155  while (nodeIterator.hasNext()) {
156  MatrixTreeNode node = (MatrixTreeNode) nodeIterator.next();
157  if (node != null) {
158  linkIds[i] = node.getLinkid();
159  i++;
160  }
161  }
162  return linkIds;
163  }
164 
165  public Iterator getTreeNodes() {
166  return nodes.values().iterator();
167  }
168 
173  public AssetType getType() {
174  return type;
175  }
176 
181  public int getStatus() {
182  return status;
183  }
184 
189  public String getURL() {
190  return url;
191  }
192 
197  public String getWebPath() {
198  return webPath;
199  }
200 
205  public boolean isAccessible() {
206  return accessible;
207  }
208 
213  public int getNumKids() {
214  return numKids;
215  }
216 
217  public void update(Element assetElement) {
218  processAssetXML(assetElement, false);
219  }
220 
221  public String processAssetXML(Element assetElement) {
222  String linkid = processAssetXML(assetElement, false);
223  return linkid;
224  }
225 
226 
231  public MatrixTreeNode processAssetXML(
232  Element assetElement,
233  MatrixTreeNode parent,
234  int index) {
235  String linkid = processAssetXML(assetElement, false);
236  if (!parent.hasChildWithLinkid(linkid))
237  return createNode(linkid, getLinkType(assetElement), parent, index);
238  return parent.getChildWithLinkid(linkid);
239  }
240 
241 
242  public boolean childrenLoaded() {
243  return childrenLoaded;
244  }
245 
246  public void setChildrenLoaded(boolean loaded) {
247  childrenLoaded = loaded;
248  }
249 
255  //public Iterator getTreeNodes() {
256  // return nodes.iterator();
257  //}
258 
267  public MatrixTreeNode[] getNodesWithLinkid(String linkid) {
268  Iterator nodes = getTreeNodes();
269  List wantedNodes = null;
270  while (nodes.hasNext()) {
271  MatrixTreeNode node = (MatrixTreeNode) nodes.next();
272  if (node.getLinkid().equals(linkid)) {
273  // lazily create
274  if (wantedNodes == null)
275  wantedNodes = new ArrayList();
276  wantedNodes.add(node);
277  }
278  }
279  if (wantedNodes == null) {
280  return new MatrixTreeNode[0];
281  } else {
282  return (MatrixTreeNode[]) wantedNodes.toArray(
283  new MatrixTreeNode[wantedNodes.size()]);
284  }
285  }
286 
287  public void propagateNode(Asset childAsset, String linkid, int linkType, int index) {
288  Iterator nodeIterator = getTreeNodes();
289 
290  DefaultTreeModel[] components = MatrixTreeModelBus.getBusComponents();
291 
292  while (nodeIterator.hasNext()) {
293  MatrixTreeNode node = (MatrixTreeNode) nodeIterator.next();
294 
295  // We need a way of checking if the shadow asset already exists, because all the
296  // linkids are the same. So loop over all the children of the parent and check
297  // if the names are the same. Unfortunately this is the only check...
298  Enumeration children = node.children();
299  boolean childExists = false;
300  while (children.hasMoreElements()) {
301  MatrixTreeNode fellowChild = (MatrixTreeNode) children.nextElement();
302  if (fellowChild.getName() == childAsset.getName(linkid))
303  childExists = true;
304  }
305 
306  MatrixTreeNode child = node.getChildWithLinkid(linkid);
307 
308  if (child == null || (AssetManager.isShadowAsset(childAsset) && !childExists)) {
309  //childAsset.createNode(linkid, linkType, node, index);
310  } else if (!AssetManager.isShadowAsset(childAsset)) {
311  if (node.hasPreviousNode()) {
312  index++;
313  }
314  if (node.getIndex(child) != index) {
315  MatrixTreeModelBus.moveNode(child, node, index);
316  }
317  }
318  }
319  }
320 
321  public void propagateChildren(MatrixTreeNode node) {
322  Iterator nodes = getTreeNodes();
323  while (nodes.hasNext()) {
324  MatrixTreeNode nextNode = (MatrixTreeNode) nodes.next();
325 
326  // find the first node that has children and propogate its
327  // children to this node
328  if (nextNode.getChildCount() > 0) {
329  Enumeration children = nextNode.children();
330  int index = 0;
331  while (children.hasMoreElements()) {
332  MatrixTreeNode childNode
333  = (MatrixTreeNode) children.nextElement();
334  MatrixTreeNode newChild =
335  childNode.getAsset().createNode(
336  childNode.getLinkid(),
337  childNode.getLinkType(),
338  node
339  );
340 
341  // we only want to insert the nodes into the current tree
342  // that we are accessing to save on memory consumption
343  MatrixTree tree = MatrixTreeBus.getLastExpandedTree();
344  ((DefaultTreeModel) tree.getModel()).insertNodeInto(newChild, node, index);
345  index++;
346  }
347  return;
348  }
349  }
350  }
351 
360  public Color getStatusColour() {
361  switch (status) {
362  case ARCHIVED:
363  return ARCHIVED_COLOUR;
364  case UNDER_CONSTRUCTION:
366  case LIVE:
367  return LIVE_COLOUR;
368  case LIVE_APPROVAL:
369  return LIVE_APPROVAL_COLOUR;
370  case PENDING_APPROVAL:
372  case APPROVED:
373  return APPROVED_COLOUR;
374  case EDITING:
375  return EDITING_COLOUR;
376  case EDITING_APPROVAL:
378  case EDITING_APPROVED:
380  default:
381  //System.err.println("Unknown status :" + status);
382  return UNKNOWN_STATUS_COLOUR;
383  }
384  }
385 
386 
387  private boolean setNodeSortOrder(String linkid, int sort_order) {
388  MatrixTreeNode[] nodes = getNodesWithLinkid(linkid);
389  boolean changed = false;
390  for (int i = 0; i < nodes.length; i++) {
391  if (nodes[i].getSortOrder() != sort_order) {
392  nodes[i].setSortOrder(sort_order);
393  changed = true;
394  }
395  }
396  return changed;
397  }
398 
399  //}}}
400  //{{{ Protected Methods
401 
402  protected String processAssetXML(Element assetElement, boolean create) {
403 
404  String linkid = "", name = "", typeCode = "";
405  boolean accessible = false;
406  int linkType = 0, status = 0, numKids = 0;
407  boolean hasLinkType = false, hasStatus = false, hasName = false,
408  hasAccessible = false, hasUrl = false, hasWebPath = false, hasSortOrder = false,
409  hasNumKids = false, hasTypeCode = false;
410  AssetType type = this.type;
411 
412  if (assetElement.hasAttribute("linkid"))
413  linkid = MatrixToolkit.rawUrlDecode(assetElement.getAttribute("linkid"));
414 
415 
416 
417  // the following attributes can be modified after creation
418  try {
419  if (assetElement.hasAttribute("type_code")) {
420  typeCode = assetElement.getAttribute("type_code");
421  type = AssetManager.getAssetType(typeCode);
422  hasTypeCode = true;
423  }
424  if (assetElement.hasAttribute("name")) {
425  name = MatrixToolkit.rawUrlDecode(assetElement.getAttribute("name"));
426  hasName = true;
427  }
428 
429  if (assetElement.hasAttribute("link_type")) {
430  linkType = Integer.parseInt(assetElement.getAttribute("link_type"));
431  hasLinkType = true;
432  }
433  if (assetElement.hasAttribute("status")) {
434  status = Integer.parseInt(assetElement.getAttribute("status"));
435  hasStatus = true;
436  }
437  if (assetElement.hasAttribute("num_kids")) {
438  numKids = Integer.parseInt(assetElement.getAttribute("num_kids"));
439  hasNumKids = true;
440  }
441  if (assetElement.hasAttribute("accessible")) {
442  accessible = assetElement.getAttribute("accessible").equals("1");
443  hasAccessible = true;
444  }
445  if (assetElement.hasAttribute("url")) {
446  String url = assetElement.getAttribute("url");
447  hasUrl = true;
448  }
449  if (assetElement.hasAttribute("web_path")) {
450  String webPath = assetElement.getAttribute("web_path");
451  hasWebPath = true;
452  }
453  if (assetElement.hasAttribute("sort_order")) {
454  this.sort_order = Integer.parseInt(assetElement.getAttribute("sort_order"));
455  hasSortOrder = true;
456  }
457 
458  } catch (NumberFormatException exp) {
459  System.out.println(exp.getMessage());
460  }
461 
462  if (create) {
463  this.initName = name;
464  this.accessible = accessible;
465  this.status = status;
466  this.url = url;
467  this.webPath = webPath;
468  this.numKids = numKids;
469  this.type = AssetManager.getAssetType(typeCode);
470  } else {
471  this.initName = name;
472  boolean refresh = false;
473 
474  // TODO: Change this back to what it was
475  boolean linkTypeChanged = setLinkType(linkType, linkid);
476 
477  if (linkTypeChanged)
478  Log.log("Link Type changed for asset " + id, Asset.class);
479 
480  // the following properties require that an event
481  // is fired to notify that the nodes of this asset
482  // have visually changed
483  refresh |= hasName && setName(name, linkid);
484  refresh |= hasStatus && setStatus(status);
485  refresh |= hasLinkType && linkTypeChanged;
486  refresh |= hasAccessible && setAccessible(accessible);
487  refresh |= hasNumKids && setNumKids(numKids);
488  refresh |= hasTypeCode && setTypeCode(type);
489  refresh |= hasSortOrder && setNodeSortOrder(linkid, this.sort_order);
490 
491  if (refresh)
492  nodesChanged();
493  if (hasUrl && setUrl(url))
494  updateUrls();
495  if (hasWebPath && setWebPath(webPath))
496  updateWebPaths();
497  }
498  return linkid;
499  }
500 
501  protected MatrixTreeNode createNode(
502  String linkid,
503  int linkType,
504  MatrixTreeNode parent,
505  int index) {
506  MatrixTreeNode node = createNode(linkid, linkType, parent);
507  if (parent != null) {
508  MatrixTreeModelBus.insertNodeInto(node, parent, index);
509  }
510  return node;
511  }
512 
521  protected MatrixTreeNode createNode(String linkid, int linkType, MatrixTreeNode parent) {
522  MatrixTreeNode node = new MatrixTreeNode(
523  this,
524  linkid,
525  linkType,
526  getNodeURL(parent),
527  webPath,
528  this.initName,
529  this.sort_order
530  );
531  addNode(node, linkid);
532 
533  return node;
534  }
535 
536 
537 
538  //}}}
539  //{{{ Package Private Methods
540 
548  void removeDiffChildNodes(String[] linkids) {
549  Iterator nodeIterator = getTreeNodes();
550  List staleNodes = null;
551  boolean found = false;
552 
553  // foreach of the nodes that this asset prepresents...
554  while (nodeIterator.hasNext()) {
555  MatrixTreeNode node = (MatrixTreeNode) nodeIterator.next();
556  Enumeration children = node.children();
557  // loop over all the child nodes of this asset
558  // and see if any of nodes are not in the specfied linkids.
559  // If they are not, we need to remove them.
560  while (children.hasMoreElements()) {
561  MatrixTreeNode childNode = (MatrixTreeNode) children.nextElement();
562 
563  if (childNode instanceof ExpandingNextNode && (node.getChildCount() >= AssetManager.getLimit())) {
564  continue;
565  } else if (childNode instanceof ExpandingPreviousNode && (getTotalKidsLoaded() > 0 )) {
566  continue;
567  }
568 
569  String linkid = childNode.getLinkid();
570  found = false;
571  for (int i = 0; i < linkids.length; i++) {
572  if (linkids[i].equals(linkid)) {
573  found = true;
574  break;
575  }
576  }
577  if (!found) {
578  // lazily create
579  if (staleNodes == null)
580  staleNodes = new ArrayList();
581  staleNodes.add(childNode);
582  }
583 
584  }
585  }
586 
587  if (staleNodes != null) {
588  Iterator staleIterator = staleNodes.iterator();
589  DefaultTreeModel[] components = MatrixTreeModelBus.getBusComponents();
590  while (staleIterator.hasNext()) {
591  MatrixTreeNode node = (MatrixTreeNode) staleIterator.next();
592  // do not want to remove next, and previous nodes
593  if (node instanceof ExpandingPreviousNode) {
594  // we have to set the previous node as the first child
595  MatrixTreeNode parent = (MatrixTreeNode)node.getParent();
596  parent.insert(node,0);
597  for (int i = 0; i < components.length; i++) {
598  DefaultTreeModel model = components[i];
599  model.nodeStructureChanged(parent);
600  }
601  } else {
602  Log.log("removing " + node + " in Asset", Asset.class);
603  MatrixTreeModelBus.removeNodeFromParent(node);
604  }
605  }
606  }
607  }
608 
609  void updateChildren() {}
610 
611  //}}}
612  //{{{ Private Methods
613 
614  private void nodesChanged() {
615  Iterator nodeIterator = getTreeNodes();
616  while (nodeIterator.hasNext()) {
617  MatrixTreeNode node = (MatrixTreeNode) nodeIterator.next();
618 
619  // boolean to control the refresh of the ExpandingNodes
620  boolean removedNext = false;
621  boolean removedPrev = false;
622 
623  if (!node.hasNextNode() && node.getChildCount() >= AssetManager.getLimit() && getNumKids() > AssetManager.getLimit() && node.getParent() != null) {
624  // BUG1666-1, added condition to check number of kids
625  // getChildCount have not been updated here, i.e. the count is from the previous run
626  MatrixTreeNode nextNode = (MatrixTreeNode) new ExpandingNextNode(getNumKids(), node.getChildCount(), getTotalKidsLoaded());
627  MatrixTreeModelBus.insertNodeInto((MatrixTreeNode) nextNode, node, node.getChildCount());
628  } else if (node.hasNextNode() && (getNumKids() <= AssetManager.getLimit())) {
629  // TODO:
630  // when the last asset in the current set is removed, the nextNode should be removed
631  // and the assetmap should show the previous set automatically
632  MatrixTreeNode nextNode = (MatrixTreeNode) node.getChildAt(node.getChildCount()-1);
633  MatrixTreeModelBus.removeNodeFromParent(nextNode);
634  removedNext = true;
635  }
636 
637  if (node.hasPreviousNode() && (getNumKids() == 0)) {
638  MatrixTreeNode prevNode = (MatrixTreeNode) node.getChildAt(0);
639  MatrixTreeModelBus.removeNodeFromParent(prevNode);
640  removedPrev = true;
641  }
642 
643  // update the count and the name, then notify the bus for refresh, BUG 1538
644  if (node.hasPreviousNode() && !removedPrev) {
645  ExpandingNode prevNode = (ExpandingNode) node.getChildAt(0);
646  prevNode.setParentTotalAssets(getNumKids());
647  prevNode.setName(prevNode.getName());
648  MatrixTreeModelBus.nodeChanged(prevNode);
649  }
650  if (node.hasNextNode() && !removedNext) {
651  ExpandingNode nextNode = (ExpandingNode) node.getChildAt(node.getChildCount()-1);
652  nextNode.setParentTotalAssets(getNumKids());
653  nextNode.setName(nextNode.getName());
654  MatrixTreeModelBus.nodeChanged(nextNode);
655  }
656 
657  MatrixTreeModelBus.nodeChanged(node);
658  }
659  }
660 
661  private void updateUrls() {
662  Iterator nodeIterator = getTreeNodes();
663  while (nodeIterator.hasNext()) {
664  MatrixTreeNode node = (MatrixTreeNode) nodeIterator.next();
665  node.propagateUrl(url);
666  }
667  }
668 
669  private void updateWebPaths() {
670  Iterator nodeIterator = getTreeNodes();
671  while (nodeIterator.hasNext()) {
672  MatrixTreeNode node = (MatrixTreeNode) nodeIterator.next();
673  node.propagateWebPath(webPath);
674  }
675  }
676 
681  private String getNodeURL(MatrixTreeNode parent) {
682  // if we have a url then we are an entity like a site
683  // so set the url to our url, otherwise use the parent's url
684  String nodeUrl = "";
685  if (url != null && (!url.equals("")))
686  nodeUrl = url;
687  else if (parent != null)
688  nodeUrl = parent.getURL();
689  return nodeUrl;
690  }
691 
692  private boolean setNumKids(int count) {
693  if (numKids == count)
694  return false;
695  numKids = count;
696 
697  // reset node set count if this node no longer has any kids
698  if (numKids == 0) {
699  setTotalKidsLoaded(0);
700  }
701 
702  return true;
703  }
704 
705  private boolean setStatus(int newStatus) {
706  if (status == newStatus)
707  return false;
708  status = newStatus;
709  return true;
710  }
711 
712  private boolean setTypeCode(AssetType newTypeCode) {
713  if (type.equals(newTypeCode))
714  return false;
715  type = newTypeCode;
716  return true;
717  }
718 
719  protected int getLinkType(Element assetElement) {
720  return Integer.parseInt(assetElement.getAttribute("link_type"));
721  }
722 
723  private boolean setLinkType(Element assetElement, String linkid) {
724  return setLinkType(getLinkType(assetElement), linkid);
725  }
726 
727  private boolean setLinkType(int newLinkType, String linkid) {
728  MatrixTreeNode[] nodes = getNodesWithLinkid(linkid);
729  boolean changed = false;
730  for (int i = 0; i < nodes.length; i++) {
731  if (nodes[i].getLinkType() != newLinkType) {
732  nodes[i].setLinkType(newLinkType);
733  changed = true;
734  }
735  }
736  return changed;
737  }
738 
739  private boolean setAccessible(boolean isAccessible) {
740  if (accessible == isAccessible)
741  return false;
742  accessible = isAccessible;
743  return true;
744  }
745 
746  private boolean setUrl(String newUrl) {
747  if (url.equals(newUrl))
748  return false;
749  url = newUrl;
750  return true;
751  }
752 
753  private boolean setWebPath(String newWebPath) {
754  if (webPath.equals(newWebPath))
755  return false;
756  webPath = newWebPath;
757  return true;
758  }
759 }
760