use of org.apache.jackrabbit.core.state.NodeState in project jackrabbit by apache.
the class NodeIndexer method addParentChildRelation.
/**
* Adds a parent child relation to the given <code>doc</code>.
*
* @param doc the document.
* @param parentId the id of the parent node.
* @throws ItemStateException if the parent node cannot be read.
* @throws RepositoryException if the parent node does not have a child node
* entry for the current node.
*/
protected void addParentChildRelation(Document doc, NodeId parentId) throws ItemStateException, RepositoryException {
Field parentField = new Field(FieldNames.PARENT, false, parentId.toString(), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO);
parentField.setIndexOptions(FieldInfo.IndexOptions.DOCS_ONLY);
doc.add(parentField);
NodeState parent = (NodeState) stateProvider.getItemState(parentId);
ChildNodeEntry child = parent.getChildNodeEntry(node.getNodeId());
if (child == null) {
// is running in a cluster.
throw new RepositoryException("Missing child node entry for node with id: " + node.getNodeId());
}
Name name = child.getName();
addNodeName(doc, name.getNamespaceURI(), name.getLocalName());
}
use of org.apache.jackrabbit.core.state.NodeState in project jackrabbit by apache.
the class SearchIndex method mergeAggregatedNodeIndexes.
/**
* Merges the fulltext indexed fields of the aggregated node states into
* <code>doc</code>.
*
* @param state the node state on which <code>doc</code> was created.
* @param doc the lucene document with index fields from <code>state</code>.
* @param ifv the current index format version.
*/
protected void mergeAggregatedNodeIndexes(NodeState state, Document doc, IndexFormatVersion ifv) {
if (indexingConfig != null) {
AggregateRule[] aggregateRules = indexingConfig.getAggregateRules();
if (aggregateRules == null) {
return;
}
try {
ItemStateManager ism = getContext().getItemStateManager();
for (AggregateRule aggregateRule : aggregateRules) {
boolean ruleMatched = false;
// node includes
NodeState[] aggregates = aggregateRule.getAggregatedNodeStates(state);
if (aggregates != null) {
ruleMatched = true;
for (NodeState aggregate : aggregates) {
Document aDoc = createDocument(aggregate, getNamespaceMappings(), ifv);
// transfer fields to doc if there are any
Fieldable[] fulltextFields = aDoc.getFieldables(FieldNames.FULLTEXT);
if (fulltextFields != null) {
for (Fieldable fulltextField : fulltextFields) {
doc.add(fulltextField);
}
doc.add(new Field(FieldNames.AGGREGATED_NODE_UUID, false, aggregate.getNodeId().toString(), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));
}
}
// make sure that fulltext fields are aligned properly
// first all stored fields, then remaining
Fieldable[] fulltextFields = doc.getFieldables(FieldNames.FULLTEXT);
doc.removeFields(FieldNames.FULLTEXT);
Arrays.sort(fulltextFields, FIELDS_COMPARATOR_STORED);
for (Fieldable f : fulltextFields) {
doc.add(f);
}
}
// property includes
PropertyState[] propStates = aggregateRule.getAggregatedPropertyStates(state);
if (propStates != null) {
ruleMatched = true;
for (PropertyState propState : propStates) {
String namePrefix = FieldNames.createNamedValue(getNamespaceMappings().translateName(propState.getName()), "");
NodeState parent = (NodeState) ism.getItemState(propState.getParentId());
Document aDoc = createDocument(parent, getNamespaceMappings(), ifv);
try {
// find the right fields to transfer
Fieldable[] fields = aDoc.getFieldables(FieldNames.PROPERTIES);
for (Fieldable field : fields) {
// assume properties fields use SingleTokenStream
TokenStream tokenStream = field.tokenStreamValue();
TermAttribute termAttribute = tokenStream.addAttribute(TermAttribute.class);
PayloadAttribute payloadAttribute = tokenStream.addAttribute(PayloadAttribute.class);
tokenStream.incrementToken();
tokenStream.end();
tokenStream.close();
String value = new String(termAttribute.termBuffer(), 0, termAttribute.termLength());
if (value.startsWith(namePrefix)) {
// extract value
String rawValue = value.substring(namePrefix.length());
// create new named value
Path p = getRelativePath(state, propState);
String path = getNamespaceMappings().translatePath(p);
value = FieldNames.createNamedValue(path, rawValue);
termAttribute.setTermBuffer(value);
PropertyMetaData pdm = PropertyMetaData.fromByteArray(payloadAttribute.getPayload().getData());
doc.add(new Field(field.name(), new SingletonTokenStream(value, pdm.getPropertyType())));
doc.add(new Field(FieldNames.AGGREGATED_NODE_UUID, false, parent.getNodeId().toString(), Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO));
if (pdm.getPropertyType() == PropertyType.STRING) {
// add to fulltext index
Field ft = new Field(FieldNames.FULLTEXT, false, rawValue, Field.Store.YES, Field.Index.ANALYZED_NO_NORMS, Field.TermVector.NO);
doc.add(ft);
}
}
}
} finally {
Util.disposeDocument(aDoc);
}
}
}
// only use first aggregate definition that matches
if (ruleMatched) {
break;
}
}
} catch (NoSuchItemStateException e) {
// do not fail if aggregate cannot be created
log.info("Exception while building indexing aggregate for {}. Node is not available {}.", state.getNodeId(), e.getMessage());
} catch (Exception e) {
// do not fail if aggregate cannot be created
log.warn("Exception while building indexing aggregate for " + state.getNodeId(), e);
}
}
}
use of org.apache.jackrabbit.core.state.NodeState in project jackrabbit by apache.
the class NodeImpl method addShareParent.
/**
* Add a share-parent to this node. This method checks, whether:
* <ul>
* <li>this node is shareable</li>
* <li>adding the given would create a share cycle</li>
* <li>the given parent is already a share-parent</li>
* </ul>
* @param parentId parent to add to the shared set
* @throws RepositoryException if an error occurs
*/
void addShareParent(NodeId parentId) throws RepositoryException {
// verify that we're shareable
if (!isShareable()) {
String msg = this + " is not shareable.";
log.debug(msg);
throw new RepositoryException(msg);
}
// detect share cycle
NodeId srcId = getNodeId();
HierarchyManager hierMgr = sessionContext.getHierarchyManager();
if (parentId.equals(srcId) || hierMgr.isAncestor(srcId, parentId)) {
String msg = "This would create a share cycle.";
log.debug(msg);
throw new RepositoryException(msg);
}
// quickly verify whether the share is already contained before creating
// a transient state in vain
NodeState state = data.getNodeState();
if (!state.containsShare(parentId)) {
state = (NodeState) getOrCreateTransientItemState();
if (state.addShare(parentId)) {
return;
}
}
String msg = "Adding a shareable node twice to the same parent is not supported.";
log.debug(msg);
throw new UnsupportedRepositoryOperationException(msg);
}
use of org.apache.jackrabbit.core.state.NodeState in project jackrabbit by apache.
the class NodeImpl method getIndex.
/**
* {@inheritDoc}
*/
public int getIndex() throws RepositoryException {
// check state of this instance
sanityCheck();
NodeId parentId = getParentId();
if (parentId == null) {
// the root node cannot have same-name siblings; always return 1
return 1;
}
try {
NodeState parent = (NodeState) stateMgr.getItemState(parentId);
ChildNodeEntry parentEntry = parent.getChildNodeEntry(getNodeId());
return parentEntry.getIndex();
} catch (ItemStateException ise) {
// should never get here...
String msg = "internal error: failed to determine index";
log.error(msg, ise);
throw new RepositoryException(msg, ise);
}
}
use of org.apache.jackrabbit.core.state.NodeState in project jackrabbit by apache.
the class NodeImpl method clone.
/**
* Create a child node that is a clone of a shareable node.
*
* @param src shareable source node
* @param name name of new node
* @return child node
* @throws ItemExistsException if there already is a child node with the
* name given and the definition does not allow creating another one
* @throws VersionException if this node is not checked out
* @throws ConstraintViolationException if no definition is found in this
* node that would allow creating the child node
* @throws LockException if this node is locked
* @throws RepositoryException if some other error occurs
*/
public synchronized NodeImpl clone(NodeImpl src, Name name) throws ItemExistsException, VersionException, ConstraintViolationException, LockException, RepositoryException {
Path nodePath;
try {
nodePath = PathFactoryImpl.getInstance().create(getPrimaryPath(), name, true);
} catch (MalformedPathException e) {
// should never happen
String msg = "internal error: invalid path " + this;
log.debug(msg);
throw new RepositoryException(msg, e);
}
// (1) make sure that parent node is checked-out
// (2) check lock status
// (3) check protected flag of parent (i.e. this) node
int options = ItemValidator.CHECK_LOCK | ItemValidator.CHECK_CHECKED_OUT | ItemValidator.CHECK_CONSTRAINTS;
sessionContext.getItemValidator().checkModify(this, options, Permission.NONE);
// (4) check for name collisions
NodeDefinitionImpl def;
try {
def = getApplicableChildNodeDefinition(name, null);
} catch (RepositoryException re) {
String msg = "no definition found in parent node's node type for new node";
log.debug(msg);
throw new ConstraintViolationException(msg, re);
}
NodeState thisState = data.getNodeState();
ChildNodeEntry cne = thisState.getChildNodeEntry(name, 1);
if (cne != null) {
// check same-name sibling setting of new node
if (!def.allowsSameNameSiblings()) {
throw new ItemExistsException(itemMgr.safeGetJCRPath(nodePath));
}
// check same-name sibling setting of existing node
NodeId newId = cne.getId();
if (!((NodeImpl) itemMgr.getItem(newId)).getDefinition().allowsSameNameSiblings()) {
throw new ItemExistsException(itemMgr.safeGetJCRPath(nodePath));
}
}
// (5) do clone operation
NodeId parentId = getNodeId();
src.addShareParent(parentId);
// (6) modify the state of 'this', i.e. the parent node
NodeId srcId = src.getNodeId();
thisState = (NodeState) getOrCreateTransientItemState();
// add new child node entry
thisState.addChildNodeEntry(name, srcId);
return itemMgr.getNode(srcId, parentId);
}
Aggregations