@Override public Document resolvePath(String path) throws NoSuchDocumentException { if (path.endsWith("/") && path.length() > 1) { path = path.substring(0, path.length() - 1); } Node node = session.getNodeByPath(path, session.getRootNode()); Document doc = newDocument(node); if (doc == null) { throw new NoSuchDocumentException(path); } return doc; }
// "readonly" meaningful for proxies and versions, used for import private Document newDocument(Node node, boolean readonly) { if (node == null) { // root's parent return null; } Node targetNode = null; String typeName = node.getPrimaryType(); if (node.isProxy()) { Serializable targetId = node.getSimpleProperty(Model.PROXY_TARGET_PROP).getValue(); if (targetId == null) { throw new NoSuchDocumentException("Proxy has null target"); } targetNode = session.getNodeById(targetId); typeName = targetNode.getPrimaryType(); } SchemaManager schemaManager = Framework.getLocalService(SchemaManager.class); DocumentType type = schemaManager.getDocumentType(typeName); if (type == null) { throw new NoSuchDocumentException("Unknown document type: " + typeName); } if (node.isProxy()) { // proxy seen as a normal document Document proxy = new SQLDocumentLive(node, type, this, false); Document target = newDocument(targetNode, readonly); return new SQLDocumentProxy(proxy, target); } else if (node.isVersion()) { return new SQLDocumentVersion(node, type, this, readonly); } else { return new SQLDocumentLive(node, type, this, false); } }
@Override public boolean isLive() { // session can become non-live behind our back // through ConnectionAwareXAResource that closes // all handles (sessions) at tx end() time return session != null && session.isLive(); }
protected Document getChild(Node node, String name) throws NoSuchDocumentException { Node childNode = session.getChildNode(node, name, false); Document doc = newDocument(childNode); if (doc == null) { throw new NoSuchDocumentException(name); } return doc; }
public Document getLastVersion(String versionSeriesId) { Serializable vid = idFromString(versionSeriesId); Node versionNode = session.getLastVersion(vid); if (versionNode == null) { return null; } return newDocument(versionNode); }
protected Node getChildPropertyForWrite(Node node, String name, String typeName) { Node childNode = getChildProperty(node, name, typeName); if (childNode == null) { // create the needed complex property immediately childNode = session.addChildNode(node, name, null, typeName, true); } return childNode; }
@Override public DocumentModelList query( String query, String queryType, QueryFilter queryFilter, long countUpTo) throws QueryException { try { // do ORDER BY ecm:path by hand in SQLQueryResult as we can't // do it in SQL (and has to do limit/offset as well) Boolean orderByPath; Matcher matcher = ORDER_BY_PATH_ASC.matcher(query); if (matcher.matches()) { orderByPath = Boolean.TRUE; // ASC } else { matcher = ORDER_BY_PATH_DESC.matcher(query); if (matcher.matches()) { orderByPath = Boolean.FALSE; // DESC } else { orderByPath = null; } } long limit = 0; long offset = 0; if (orderByPath != null) { query = matcher.group(1); limit = queryFilter.getLimit(); offset = queryFilter.getOffset(); queryFilter = QueryFilter.withoutLimitOffset(queryFilter); } PartialList<Serializable> pl = session.query(query, queryType, queryFilter, countUpTo); List<Serializable> ids = pl.list; // get Documents in bulk List<Document> docs = getDocumentsById(ids); // build DocumentModels from Documents String[] schemas = {"common"}; List<DocumentModel> list = new ArrayList<DocumentModel>(ids.size()); for (Document doc : docs) { list.add(DocumentModelFactory.createDocumentModel(doc, schemas)); } // order / limit if (orderByPath != null) { Collections.sort(list, new PathComparator(orderByPath.booleanValue())); } if (limit != 0) { // do limit/offset by hand int size = list.size(); list.subList(0, (int) (offset > size ? size : offset)).clear(); size = list.size(); if (limit < size) { list.subList((int) limit, size).clear(); } } return new DocumentModelListImpl(list, pl.totalSize); } catch (QueryParseException e) { throw new QueryException(e.getMessage() + ": " + query, e); } }
protected Node getChildProperty(Node node, String name, String typeName) { // all complex property children have already been created by SessionImpl.addChildNode or // SessionImpl.addMixinType // if one is missing here, it means that it was concurrently deleted and we're only now finding // out // or that a schema change was done and we now expect a new child // return null in that case return session.getChildNode(node, name, true); }
@Override public void close() { root = null; try { session.close(); } catch (ResourceException e) { throw new RuntimeException(e); } }
protected List<Document> getVersions(String versionSeriesId) { Serializable vid = idFromString(versionSeriesId); List<Node> versionNodes = session.getVersions(vid); List<Document> versions = new ArrayList<Document>(versionNodes.size()); for (Node versionNode : versionNodes) { versions.add(newDocument(versionNode)); } return versions; }
public SQLSession( org.nuxeo.ecm.core.storage.sql.Session session, Repository repository, String sessionId) { this.session = session; this.repository = repository; Node rootNode = session.getRootNode(); this.sessionId = sessionId; root = newDocument(rootNode); negativeAclAllowed = Framework.isBooleanPropertyTrue(ALLOW_NEGATIVE_ACL_PROPERTY); copyFindFreeNameDisabled = Framework.isBooleanPropertyTrue(COPY_FINDFREENAME_DISABLED_PROP); }
@Override public Document move(Document source, Document parent, String name) { assert source instanceof SQLDocument; assert parent instanceof SQLDocument; if (name == null) { name = source.getName(); } Node result = session.move(((SQLDocument) source).getNode(), ((SQLDocument) parent).getNode(), name); return newDocument(result); }
protected String findFreeName(Node parentNode, String name) { if (session.hasChildNode(parentNode, name, false)) { Matcher m = dotDigitsPattern.matcher(name); if (m.matches()) { // remove trailing dot and digits name = m.group(1); } // add dot + unique digits name += "." + System.nanoTime(); } return name; }
@Override public Collection<Document> getProxies(Document document, Document parent) { Collection<Node> proxyNodes = session.getProxies( ((SQLDocument) document).getNode(), parent == null ? null : ((SQLDocument) parent).getNode()); List<Document> proxies = new ArrayList<Document>(proxyNodes.size()); for (Node proxyNode : proxyNodes) { proxies.add(newDocument(proxyNode)); } return proxies; }
protected List<Document> getChildren(Node node) { List<Node> nodes = session.getChildren(node, null, false); List<Document> children = new ArrayList<Document>(nodes.size()); for (Node n : nodes) { try { children.add(newDocument(n)); } catch (NoSuchDocumentException e) { // ignore error retrieving one of the children continue; } } return children; }
@Override public Document getVersion(String versionableId, VersionModel versionModel) { Serializable vid = idFromString(versionableId); Node versionNode = session.getVersionByLabel(vid, versionModel.getLabel()); if (versionNode == null) { return null; } versionModel.setDescription( versionNode.getSimpleProperty(Model.VERSION_DESCRIPTION_PROP).getString()); versionModel.setCreated( (Calendar) versionNode.getSimpleProperty(Model.VERSION_CREATED_PROP).getValue()); return newDocument(versionNode); }
protected Document importChild( String uuid, Node parent, String name, Long pos, String typeName, Map<String, Serializable> props) { Serializable id = idFromString(uuid); Node node = session.addChildNode(id, parent, name, pos, typeName, false); for (Entry<String, Serializable> entry : props.entrySet()) { node.setSimpleProperty(entry.getKey(), entry.getValue()); } return newDocument(node, false); // not readonly }
@Override public Document copy(Document source, Document parent, String name) { assert source instanceof SQLDocument; assert parent instanceof SQLDocument; if (name == null) { name = source.getName(); } Node parentNode = ((SQLDocument) parent).getNode(); if (!copyFindFreeNameDisabled) { name = findFreeName(parentNode, name); } Node copy = session.copy(((SQLDocument) source).getNode(), parentNode, name); return newDocument(copy); }
@Override public void setACP(Document doc, ACP acp, boolean overwrite) { if (!overwrite && acp == null) { return; } checkNegativeAcl(acp); Node node = ((SQLDocument) doc).getNode(); ACLRow[] aclrows; if (overwrite) { aclrows = acp == null ? null : acpToAclRows(acp); } else { aclrows = (ACLRow[]) node.getCollectionProperty(Model.ACL_PROP).getValue(); aclrows = updateAclRows(aclrows, acp); } node.getCollectionProperty(Model.ACL_PROP).setValue(aclrows); session.requireReadAclsUpdate(); }
@Override public Document createProxy(Document doc, Document folder) { Node folderNode = ((SQLDocument) folder).getNode(); Node targetNode = ((SQLDocument) doc).getNode(); Serializable targetId = targetNode.getId(); Serializable versionableId; if (doc.isVersion()) { versionableId = targetNode.getSimpleProperty(Model.VERSION_VERSIONABLE_PROP).getValue(); } else if (doc.isProxy()) { // copy the proxy targetId = targetNode.getSimpleProperty(Model.PROXY_TARGET_PROP).getValue(); versionableId = targetNode.getSimpleProperty(Model.PROXY_VERSIONABLE_PROP).getValue(); } else { // working copy (live document) versionableId = targetId; } String name = findFreeName(folderNode, doc.getName()); Node proxy = session.addProxy(targetId, versionableId, folderNode, name, null); return newDocument(proxy); }
// called by SQLQueryResult iterator protected List<Document> getDocumentsById(List<Serializable> ids) { List<Document> docs = new ArrayList<Document>(ids.size()); List<Node> nodes = session.getNodesByIds(ids); for (int index = 0; index < ids.size(); ++index) { Node eachNode = nodes.get(index); if (eachNode == null) { Serializable eachId = ids.get(index); log.warn("Cannot fetch document by id " + eachId, new Throwable("debug stack trace")); continue; } Document doc; try { doc = newDocument(eachNode); } catch (NoSuchDocumentException e) { // unknown type in db, ignore continue; } docs.add(doc); } return docs; }
protected Lock getLock(Node node) { return session.getLock(node.getId()); }
protected Node getNodeById(Serializable id) { return session.getNodeById(id); }
protected Document getVersionByLabel(String versionSeriesId, String label) { Serializable vid = idFromString(versionSeriesId); Node versionNode = session.getVersionByLabel(vid, label); return versionNode == null ? null : newDocument(versionNode); }
protected Document checkIn(Node node, String label, String checkinComment) { Node versionNode = session.checkIn(node, label, checkinComment); return versionNode == null ? null : newDocument(versionNode); }
protected Lock setLock(Node node, Lock lock) { return session.setLock(node.getId(), lock); }
protected Lock removeLock(Node node, String owner) { return session.removeLock(node.getId(), owner, false); }
protected void checkOut(Node node) { session.checkOut(node); }
@Override public Map<String, String> getBinaryFulltext(String id) { return session.getBinaryFulltext(idFromString(id)); }
protected void restore(Node node, Node version) { session.restore(node, version); }