1 16 package org.outerj.daisy.navigation.impl; 17 18 import org.outerj.daisy.repository.VariantKey; 19 import org.outerj.daisy.repository.RepositoryException; 20 import org.outerj.daisy.navigation.NavigationVersionMode; 21 import org.outerx.daisy.x10.SearchResultDocument; 22 import org.outerx.daisy.x10.LinkValueType; 23 import org.apache.xmlbeans.QNameSet; 24 import org.apache.xmlbeans.XmlObject; 25 import org.apache.xmlbeans.SchemaType; 26 import org.apache.xmlbeans.XmlString; 27 28 import java.util.Locale ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.HashMap ; 32 33 37 public class QueryNode extends AbstractParentNode { 38 private final String query; 39 private final String extraCond; 40 private final long navigationBranchId; 41 private final long navigationLanguageId; 42 private final NodeVisibility nodeVisibility; 43 private final CommonNavigationManager.Context context; 44 private final NavigationVersionMode versionMode; 45 private boolean loaded = false; 46 47 public QueryNode(String query, String extraCond, NodeVisibility nodeVisibility, 48 CommonNavigationManager.Context context, long navigationBranchId, long navigationLanguageId, 49 NavigationVersionMode versionMode) { 50 this.query = query; 51 this.extraCond = extraCond; 52 this.nodeVisibility = nodeVisibility; 53 this.context = context; 54 this.navigationBranchId = navigationBranchId; 55 this.navigationLanguageId = navigationLanguageId; 56 this.versionMode = versionMode; 57 } 58 59 private synchronized void load() throws RepositoryException { 60 if (!loaded) { 61 SearchResultDocument searchResult; 62 try { 63 Map queryOptions = null; 64 if (versionMode == NavigationVersionMode.LAST) { 65 queryOptions = new HashMap (4); 66 queryOptions.put("search_last_version", "true"); 67 } 68 searchResult = context.getRepository().getQueryManager().performQuery(query, extraCond, queryOptions, Locale.getDefault()); 69 } catch (Throwable e) { 70 add(new ErrorNode("(error executing query)")); 71 context.getLogger().error("Error executing query in navigation tree: " + query, e); 72 loaded = true; 73 return; 74 } 75 76 SearchResultDocument.SearchResult.Rows.Row[] rows = searchResult.getSearchResult().getRows().getRowArray(); 77 78 if (rows.length > 0) { 79 XmlObject[] values = rows[0].selectChildren(QNameSet.ALL); 81 for (int i = 0; i < values.length; i++) { 82 SchemaType schemaType = values[i].schemaType(); 83 if (schemaType != XmlString.type && schemaType != LinkValueType.type) { 84 add(new ErrorNode("(query selects unsupported type of value: " + schemaType.getShortJavaName() + ")")); 85 loaded = true; 86 return; 87 } 88 } 89 90 ParentNodeInfo[] parentNodes = new ParentNodeInfo[values.length]; 91 parentNodes[0] = new ParentNodeInfo(this, null); 92 93 for (int i = 0; i < rows.length; i++) { 94 values = rows[i].selectChildren(QNameSet.ALL); 95 int createGroupsFrom = values.length - 1; 96 for (int k = 0; k < values.length -1; k++) { 97 String label = getLabel(values[k]); 98 if (parentNodes[k + 1] == null || !(parentNodes[k + 1]).label.equals(label)) { 99 createGroupsFrom = k; 100 break; 101 } 102 } 103 for (int k = createGroupsFrom; k < values.length - 1; k++) { 104 String label = getLabel(values[k]); 105 String nodeId = NavigationUtil.makeNodeIdValid(label); 106 if (nodeId == null) 107 nodeId = "qn" + rows[i].getDocumentId(); GroupNode newGroup = new GroupNode(nodeId, label, nodeVisibility); 109 parentNodes[k + 1] = new ParentNodeInfo(newGroup, label); 110 parentNodes[k].node.add(newGroup); 111 } 112 VariantKey variantKey = new VariantKey(rows[i].getDocumentId(), rows[i].getBranchId(), rows[i].getLanguageId()); 113 DocumentFromQueryNode newNode = new DocumentFromQueryNode(variantKey, getLabel(values[values.length - 1]), nodeVisibility, context, navigationBranchId, navigationLanguageId, versionMode); 114 parentNodes[parentNodes.length -1].node.add(newNode); 115 } 116 } 117 118 loaded = true; 119 } 120 } 121 122 private String getLabel(XmlObject xmlObject) { 123 if (xmlObject instanceof XmlString) { 124 String label = ((XmlString)xmlObject).getStringValue(); 125 if (label == null || label.length() == 0) 126 return "(blank)"; 127 else 128 return label; 129 } else { 130 return xmlObject.toString(); 131 } 132 } 133 134 static final class ParentNodeInfo { 135 AbstractParentNode node; 136 String label; 137 138 public ParentNodeInfo(AbstractParentNode node, String label) { 139 this.node = node; 140 this.label = label; 141 } 142 } 143 144 public void searchPath(String [] path, int pos, long branchId, long languageId, Node[] foundPath) throws RepositoryException { 145 load(); 146 super.searchPath(path, pos, branchId, languageId, foundPath); 147 } 148 149 public List getExpandedChildList() throws RepositoryException { 150 load(); 151 return super.getExpandedChildList(); 152 } 153 154 public boolean isVisible(long userId, long[] roleId, Node[] activeNodePath, int activeNodePathPos) throws RepositoryException { 155 throw new RuntimeException ("isVisible not supported on this node."); 156 } 157 158 public boolean checkId(String id, long branchId, long languageId) { 159 throw new UnsupportedOperationException ("checkId not supported on this node."); 160 } 161 162 public boolean isExpandable() { 163 return true; 164 } 165 166 public boolean isIdentifiable() { 167 return false; 168 } 169 } 170 | Popular Tags |