Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
AssetManager.java
1 
16 package net.squiz.matrix.core;
17 
18 import net.squiz.matrix.matrixtree.*;
19 import net.squiz.matrix.debug.*;
20 import java.util.*;
21 import org.w3c.dom.*;
22 import java.io.IOException;
23 import javax.swing.*;
24 import javax.swing.event.*;
25 import javax.swing.tree.*;
26 import net.squiz.matrix.ui.*;
27 import net.squiz.matrix.assetmap.*;
28 
29 
35 public class AssetManager {
36 
37  /* The map of assets (assetid => asset) */
38  private static Map assets = new HashMap();
39  /* The map of asset types (type_code => assetType) */
40  private static Map assetTypes = new HashMap();
41  private static MatrixTreeNode root;
42  private static String currentUserid;
43  private static String currentUserType = "root_user";
44  private static String lastRequest = "";
45  private static Date now = new Date();
46  private static Date lastRequestTime = new Date(now.getTime() - (2 * 60 * 60 * 1000));
47  private static Element lastResponse = null;
48  private static String workspaceid;
49  private static boolean isInited = false;
50  private static int limit = 0;
51  //TODO: MM: thinking of a better way to do this stuff with initialisiation
52  private static EventListenerList listenerList = new EventListenerList();
53 
54  // cannot instantiate
55  private AssetManager() {}
56 
63  public static MatrixTreeNode init() throws IOException {
64 
65  if (isInited)
66  throw new IllegalStateException("Already Inited");
67 
68  Document response = null;
69  response = Matrix.doRequest("<command action=\"initialise\" />");
70  NodeList children = response.getDocumentElement().getChildNodes();
71 
72  for (int i = 0; i < children.getLength(); i++) {
73  if (!(children.item(i) instanceof Element))
74  continue;
75  Element childElement = (Element) children.item(i);
76 
77  if (childElement.getTagName().equals("asset_types")) {
78  NodeList xmlNodes = childElement.getChildNodes();
79  processAssetTypesXML(xmlNodes);
80  } else if (childElement.getTagName().equals("assets")) {
81  root = processAssetsXML(childElement);
82  }
83  }
84  fireInitialisationComplete(root);
85  isInited = true;
86 
87  return root;
88  }
89 
90  public static void addInitialisationListener(InitialisationListener l) {
91  listenerList.add(InitialisationListener.class, l);
92  }
93 
94  private static void fireInitialisationComplete(MatrixTreeNode root) {
95  // Guaranteed to return a non-null array
96  Object[] listeners = listenerList.getListenerList();
97  InitialisationEvent evt = null;
98 
99  // Process the listeners last to first, notifying
100  // those that are interested in this event
101  for (int i = listeners.length - 2; i >= 0; i -= 2) {
102  if (listeners[i] == InitialisationListener.class) {
103  // Lazily create the event:
104  if (evt == null)
105  evt = new InitialisationEvent(root, root);
106  ((InitialisationListener) listeners[i + 1]).
107  initialisationComplete(evt);
108  }
109  }
110  }
111 
117  private static void processAssetTypesXML(NodeList xmlNodes) {
118 
119  for (int i = 0; i < xmlNodes.getLength(); i++) {
120  if (!(xmlNodes.item(i) instanceof Element))
121  continue;
122  Element assetTypeElement = (Element) xmlNodes.item(i);
123 
124  AssetType type = null;
125  AssetType parentType = null;
126  String typeCode = assetTypeElement.getAttribute("type_code");
127  String parentTypeCode = assetTypeElement.getAttribute("parent_type_code");
128 
129  if (!(assetTypes.containsKey(parentTypeCode))) {
130  // create a placement for the parent asset type if it doesn't
131  // exist. We will set its info later when we come to it
132  parentType = new AssetType(parentTypeCode);
133  assetTypes.put(parentTypeCode, parentType);
134  } else {
135  parentType = getAssetType(parentTypeCode);
136  }
137 
138  if (!assetTypes.containsKey(typeCode)) {
139  type = new AssetType(typeCode);
140  assetTypes.put(typeCode, type);
141  } else {
142  type = getAssetType(typeCode);
143  }
144  type.setInfo(assetTypeElement);
145  type.setParentType(parentType);
146  }
147  }
148 
154  private static MatrixTreeNode processAssetsXML(Element rootElement) {
155  Node nextElement = null;
156  NodeList nodes = (NodeList) rootElement.getChildNodes();
157  int i = 0;
158 
159  // get the first Element which is the root folder element
160  do {
161  nextElement = nodes.item(i++);
162  } while (!(nextElement instanceof Element));
163 
164  Element rootFolderElement = (Element) nextElement;
165  RootFolder parentAsset = new RootFolder(rootFolderElement);
166  assets.put(parentAsset.getId(), parentAsset);
167  processAssetsXML(rootElement, parentAsset.getRootNode());
168 
169  return parentAsset.getRootNode();
170  }
171 
178  private static void processAssetsXML(Element rootElement, MatrixTreeNode parent) {
179  /*
180  The XML structure that is processed by this method is as follows:
181  <assets> 1
182  <asset ...> 2
183  <asset ...> 3
184  <asset ...> 3
185  </asset> 2
186  </assets> 1
187  */
188 
189 
190  NodeList parentNodes = (NodeList) rootElement.getChildNodes();
191  // level 2
192  for (int i = 0; i < parentNodes.getLength(); i++) {
193  if (!(parentNodes.item(i) instanceof Element))
194  continue;
195  Element parentElement = (Element) parentNodes.item(i);
196  NodeList childNodes = (NodeList) parentElement.getChildNodes();
197  int index = 0;
198 
199  // level 3
200  for (int j = 0; j < childNodes.getLength(); j++) {
201  if (!(childNodes.item(j) instanceof Element))
202  continue;
203  Element childElement = (Element) childNodes.item(j);
204  String assetid = getIdFromElement(childElement);
205  Asset asset = loadAsset(assetid, childElement, parent, index);
206  index++;
207  }
208  parent.getAsset().setChildrenLoaded(true);
209  }//end for
210  }
211 
212 
213  private static Asset loadAsset(
214  String assetid,
215  Element assetElement,
216  MatrixTreeNode parent,
217  int index) {
218  Asset asset = null;
219  if (!assets.containsKey(assetid)) {
220  asset = new Asset(assetElement, parent, index);
221  assets.put(assetid, asset);
222  } else {
223  asset = getAsset(assetid);
224  if (parent == null)
225  asset.processAssetXML(assetElement);
226  else
227  asset.processAssetXML(assetElement, parent, index);
228  }
229 
230  return asset;
231  }
232 
233  /*
234  * Processes the current user XML element at init time
235  * @param xmlNodes the xmlNodes that represent the current user Types
236  */
237  private static void processCurrentUserXML(Element xmlNodes) {
238  currentUserid = getIdFromElement(xmlNodes);
239  currentUserType = xmlNodes.getAttribute("type_code");
240  String name = xmlNodes.getAttribute("name");
241  }
242 
243  public static void setLimit(int newLimit) {
244  limit = newLimit;
245  }
246 
247  public static int getLimit() {
248  // default limit
249  if (limit != 0) {
250  return limit;
251  } else if (Matrix.getProperty("parameter.asset.limit") != null) {
252  limit = Integer.parseInt(Matrix.getProperty("parameter.asset.limit"));
253  } else {
254  limit = 50;
255  }
256  return limit;
257  }
258 
259  public static void refreshAsset(MatrixTreeNode parent, String direction, int start, int limit) throws IOException {
260  String[] assetids = new String[] { parent.getAsset().getId() };
261  Element element = makeRefreshRequest(assetids, direction, start, limit);
262  processAssetsXML(element, parent);
263  }
264 
265  public static void refreshAsset(MatrixTreeNode parent, String direction) throws IOException {
266  refreshAsset(parent, direction, -1, -1);
267  }
268 
269  public static int calcNextOffset(String assetid) {
270  Asset asset = getAsset(assetid);
271  asset.setTotalKidsLoaded(asset.getTotalKidsLoaded()+getLimit());
272  return asset.getTotalKidsLoaded();
273  }
274 
275  public static int calcPrevOffset(String assetid) {
276  Asset asset = getAsset(assetid);
277  asset.setTotalKidsLoaded(asset.getTotalKidsLoaded() - getLimit());
278  return asset.getTotalKidsLoaded();
279  }
280 
281 
299  public static Element makeRefreshRequest(String[] assetids, String direction, int start, int limit) throws IOException {
300 
301  int startLoc = start;
302  if (limit < 0) {
303  limit = getLimit();
304  }
305 
306  StringBuffer xml = new StringBuffer("<command action=\"get assets\" >");
307  for (int i = 0; i < assetids.length; i++) {
308 
309  if (start < 0) {
310  // start was not specified, calculate it
311  if (direction.equals("prev")) {
312  startLoc = calcPrevOffset(assetids[i]);
313  } else if (direction.equals("next")) {
314  startLoc = calcNextOffset(assetids[i]);
315  } else if (direction.equals("base")) {
316  Asset asset = getAsset(assetids[i]);
317  asset.setTotalKidsLoaded(0);
318  startLoc = 0;
319  } else {
320  Asset asset = getAsset(assetids[i]);
321  if (asset != null) {
322  startLoc = asset.getTotalKidsLoaded();
323  }
324  }
325  } else {
326  Asset asset = getAsset(assetids[i]);
327  if (asset != null) {
328  asset.setTotalKidsLoaded(startLoc);
329  }
330  }
331 
332  Asset asset = getAsset(assetids[i]);
333  if (asset != null) {
334  String[] linkids = asset.getLinkIds();
335  if (assetids[i].equals("1")) {
336  MatrixToolkit.addAssetToXML(xml, assetids[i], "0", startLoc, limit);
337  } else {
338  for (int j=0; j< linkids.length; j++) {
339  MatrixToolkit.addAssetToXML(xml, assetids[i], linkids[j], startLoc, limit);
340  }
341  }
342  }
343  }
344  xml.append("</command>");
345 
346  // If the request is the same as the last just sent out, why bother doing it again?
347  Date currentTime = new Date(System.currentTimeMillis());
348  long diffResponse = (currentTime.getTime() - lastRequestTime.getTime());
349  Element currentElement = null;
350  if (lastRequest.equals(xml.toString()) && (diffResponse >= 0 && diffResponse < 2000) && lastResponse != null) {
351  currentElement = lastResponse;
352  } else {
353  Document doc = Matrix.doRequest(xml.toString());
354  // Remember the last request/response
355  lastRequest = xml.toString();
356  lastRequestTime = new Date(System.currentTimeMillis());
357  lastResponse = doc.getDocumentElement();
358  currentElement = doc.getDocumentElement();
359  }
360 
361  return currentElement;
362 
363 // Document doc = Matrix.doRequest(xml.toString());
364 // return doc.getDocumentElement();
365  }
366 
367  public static Element makeRefreshRequest(String[] assetids, String direction) throws IOException {
368  return makeRefreshRequest(assetids, direction, -1, -1);
369  }
370 
371  public static void refreshAssets(Element element) {
372  NodeList childNodes = (NodeList) element.getChildNodes();
373  for (int i = 0; i < childNodes.getLength(); i++) {
374  if (!(childNodes.item(i) instanceof Element))
375  continue;
376  Element assetElement = (Element) childNodes.item(i);
377  updateAsset(assetElement);
378  }
379  }
380 
381  public static String[] getAllRefreshableAssetids() {
382  Iterator iterator = assets.values().iterator();
383  List assetids = new ArrayList();
384 
385  while (iterator.hasNext()) {
386  Asset asset = (Asset) iterator.next();
387  Iterator nodes = asset.getTreeNodes();
388 
389  while(nodes.hasNext()) {
390  MatrixTreeNode node = (MatrixTreeNode) nodes.next();
391  if (node.getAsset().childrenLoaded()) {
392  assetids.add(node.getAsset().getId());
393  break;
394  }
395  }
396  }
397  return (String[]) assetids.toArray(new String[assetids.size()]);
398  }
399 
400  public static void updateAsset(Element childElement) {
401  String assetid = getIdFromElement(childElement);
402  // if we dont have this asset then we can't update it or its children
403  if (!assets.containsKey(assetid))
404  return;
405  Asset asset = getAsset(assetid);
406  updateAsset(childElement, asset);
407  }
408 
416  public static void updateAsset(Element childElement, Asset parent) {
417 
418  NodeList childNodes = (NodeList) childElement.getChildNodes();
419  parent.processAssetXML(childElement);
420 
421  // create a set of linkids so that we can remove any nodes
422  // that are no longer children of this asset
423  List linkids = new ArrayList();
424  boolean hasShadowChild = false;
425 
426  // assets in the xml are in the correct order. We dont use the sort
427  // order because notice links and type 3 links have a sort order, but
428  // are not shown in the tree.
429  int index = 0;
430 
431  for (int i = 0; i < childNodes.getLength(); i++) {
432 
433  if (!(childNodes.item(i) instanceof Element))
434  continue;
435  Element assetElement = (Element) childNodes.item(i);
436 
437 
438  String assetid = getIdFromElement(assetElement);
439  if (assetid.indexOf(":") != -1) {
440  hasShadowChild = true;
441  }
442  String linkid = assetElement.getAttribute("linkid");
443  int linkType = Integer.parseInt(assetElement.getAttribute("link_type"));
444  Asset asset = loadAsset(assetid, assetElement, null, index);
445  linkids.add(linkid);
446  // this node might be new so we need to give
447  // a parent a chance to add it
448  parent.propagateNode(asset, linkid, linkType, index);
449  parent.setChildrenLoaded(true);
450 
451  index++;
452  }
453 
454  // remove the children that are not currently in the matrix system
455  // if there were no nodes in the xml, this will remove all children
456  parent.removeDiffChildNodes((String[]) linkids.toArray(new String[linkids.size()]));
457 
458  try {
459  if (!parent.getId().equals("1")) {
460  // refresh parent node to update the tree
461  Iterator nodeIterator = parent.getTreeNodes();
462  while (nodeIterator.hasNext()) {
463  MatrixTreeNode node = (MatrixTreeNode) nodeIterator.next();
464  if (node != null) {
465  refreshAsset(node, "");
466  }
467  if (hasShadowChild) {
468  // bug2346: collapse and expand, as a refresh action
469  // for assets that implement bridge (e.g. form section)
470  TreePath tp = new TreePath(node.getPath());
471  if (MatrixTreeBus.getActiveTree().isExpanded(tp)) {
472  MatrixTreeBus.getActiveTree().collapsePath(tp);
473  MatrixTreeBus.getActiveTree().expandPath(tp);
474  }
475  }
476  }
477  } else {
478  // refresh root node
479  refreshAsset((MatrixTreeNode)MatrixTreeBus.getActiveTree().getModel().getRoot(), "");
480  }
481  } catch (IOException ex) {}
482  }
483 
484  public static boolean isShadowAsset(Asset asset) {
485  return (asset.getId().indexOf(":") != -1) ? true : false;
486  }
487 
488  private static String getIdFromElement(Element element) {
489  return MatrixToolkit.rawUrlDecode(element.getAttribute("assetid"));
490  }
491 
497  public static Asset getAsset(String assetid) {
498  return (Asset) assets.get(assetid);
499  }
500 
506  public static AssetType getAssetType(String typeCode) {
507  return (AssetType) assetTypes.get(typeCode);
508  }
509 
510  public static Iterator getAssetTypes() {
511  return assetTypes.values().iterator();
512  }
513 
514  public static String getWorkspaceid() {
515  return workspaceid;
516  }
517 
518  public static Asset getCurrentUser() {
519  return getAsset(currentUserid);
520  }
521 
522  public static AssetType getCurrentUserType() {
523  return getAssetType(currentUserType);
524  }
525 
526  public static MatrixTreeNode getRootFolderNode() {
527  return root;
528  }
529 
538  public static String[] getAssetsOfType(String typeCode) {
539  Iterator iterator = assets.values().iterator();
540  List assets = new ArrayList();
541  while (iterator.hasNext()) {
542  Asset asset = (Asset) iterator.next();
543  if (asset.getType().getTypeCode().equals(typeCode)) {
544  assets.add(asset.getId());
545  }
546  }
547  return (String[]) assets.toArray(new String[assets.size()]);
548  }
549 
550 
551  public static String[] getTypeCodeNames() {
552  Iterator assetTypesIterator = assetTypes.values().iterator();
553  String[] names = new String[assetTypes.size()];
554  int i = 0;
555  while (assetTypesIterator.hasNext()) {
556  AssetType type = (AssetType) assetTypesIterator.next();
557  names[i++] = type.getName();
558  }
559  return names;
560  }
561 }
562