Skip to content

Commit

Permalink
MODE-2401 Added support for handling mixins which have the "noquery" …
Browse files Browse the repository at this point in the history
…type attribute and updated the code to reflect the differences between the "noquery" types and the previously existing ModeShape noquery document attribute which has a different semantic.
  • Loading branch information
Horia Chiorean committed May 29, 2015
1 parent 8da0dd6 commit 5c65b74
Show file tree
Hide file tree
Showing 39 changed files with 387 additions and 346 deletions.
Expand Up @@ -924,31 +924,31 @@ private void fireEntryModified( ConnectorChangeSet connectorChangeSet,
connector.lastModifiedTimeFor(file));
// there is no way to observe the previous value, so fire <null>
connectorChangeSet.propertyChanged(contentId, JcrNtLexicon.RESOURCE, Collections.<Name>emptySet(), contentId, null,
modifiedProperty, queryable);
modifiedProperty);

// fire PROPERTY_CHANGED for nt:file/jcr:content/jcr:data/jcr:lastModifiedBy
String owner = connector.ownerFor(file);
if (owner != null) {
Property modifiedByProperty = connector.propertyFactory().create(JcrLexicon.LAST_MODIFIED_BY, owner);
// there is no way to observe the previous value, so fire <null>
connectorChangeSet.propertyChanged(contentId, JcrNtLexicon.RESOURCE, Collections.<Name>emptySet(), contentId,
null, modifiedByProperty, queryable);
null, modifiedByProperty);
}

try {
// fire PROPERTY_CHANGED for nt:file/jcr:content/jcr:data
BinaryValue binaryValue = connector.binaryFor(file);
Property binaryProperty = connector.propertyFactory().create(JcrLexicon.DATA, binaryValue);
connectorChangeSet.propertyChanged(contentId, JcrNtLexicon.RESOURCE, Collections.<Name>emptySet(), contentId,
null, binaryProperty, queryable);
null, binaryProperty);

if (connector.addMimeTypeMixin) {
try {
// fire PROPERTY_CHANGED for nt:file/jcr:content/jcr:mimetype
String mimeType = binaryValue.getMimeType();
Property mimeTypeProperty = connector.propertyFactory().create(JcrLexicon.MIMETYPE, mimeType);
connectorChangeSet.propertyChanged(contentId, JcrNtLexicon.RESOURCE, Collections.<Name>emptySet(),
contentId, null, mimeTypeProperty, queryable);
contentId, null, mimeTypeProperty);

} catch (Throwable e) {
connector.getLogger().error(e, JcrI18n.couldNotGetMimeType, connector.getSourceName(), contentId,
Expand Down Expand Up @@ -982,7 +982,7 @@ private void fireEntryDeleted( ConnectorChangeSet connectorChangeSet,
}

connectorChangeSet.nodeRemoved(id, connector.idFor(parentPath.toFile()), id, primaryType,
Collections.<Name>emptySet(), queryable, parentPrimaryType,
Collections.<Name>emptySet(), parentPrimaryType,
Collections.<Name>emptySet());
}

Expand All @@ -1005,37 +1005,37 @@ private void fireEntryCreated( ConnectorChangeSet connectorChangeSet,
boolean queryable = connector.isQueryable();
// fire NODE_ADDED for nt:file
connectorChangeSet.nodeCreated(docId, connector.idFor(resolvedPath.getParent().toFile()), docId, primaryType,
Collections.<Name>emptySet(), Collections.<Name, Property>emptyMap(), queryable);
Collections.<Name>emptySet(), Collections.<Name, Property>emptyMap());
// fire PROPERTY_ADDED for nt:file/jcr:created
Property createdProperty = connector.propertyFactory().create(JcrLexicon.CREATED, connector.createdTimeFor(file));
connectorChangeSet.propertyAdded(docId, primaryType, Collections.<Name>emptySet(), docId, createdProperty, queryable);
connectorChangeSet.propertyAdded(docId, primaryType, Collections.<Name>emptySet(), docId, createdProperty);

String owner = connector.ownerFor(file);
if (owner != null) {
// fire PROPERTY_ADDED for nt:file/jcr:createdBy
Property createdByProperty = connector.propertyFactory().create(JcrLexicon.CREATED_BY, owner);
connectorChangeSet.propertyAdded(docId, primaryType, Collections.<Name>emptySet(), docId, createdByProperty,
queryable);
connectorChangeSet.propertyAdded(docId, primaryType, Collections.<Name>emptySet(), docId, createdByProperty
);
}
if (Files.isRegularFile(resolvedPath, LinkOption.NOFOLLOW_LINKS)) {
// for files we need to fire extra events for their content
String contentId = connector.contentChildId(docId, false);
// fire NODE_ADDED for the nt:file/jcr:content
connectorChangeSet.nodeCreated(contentId, docId, contentId, JcrNtLexicon.RESOURCE, Collections.<Name>emptySet(),
Collections.<Name, Property>emptyMap(), queryable);
Collections.<Name, Property>emptyMap());
try {
// fire PROPERTY_ADDED for nt:file/jcr:content/jcr:data
BinaryValue binaryValue = connector.binaryFor(file);
Property dataProperty = connector.propertyFactory().create(JcrLexicon.DATA, binaryValue);
connectorChangeSet.propertyAdded(contentId, JcrNtLexicon.RESOURCE, Collections.<Name>emptySet(), contentId,
dataProperty, queryable);
dataProperty);
if (connector.addMimeTypeMixin) {
try {
// fire PROPERTY_ADDED for nt:file/jcr:content/jcr:mimetype
String mimeType = binaryValue.getMimeType();
Property mimeTypeProperty = connector.propertyFactory().create(JcrLexicon.MIMETYPE, mimeType);
connectorChangeSet.propertyAdded(contentId, JcrNtLexicon.RESOURCE, Collections.<Name>emptySet(),
contentId, mimeTypeProperty, queryable);
contentId, mimeTypeProperty);

} catch (Throwable e) {
connector.getLogger().error(e, JcrI18n.couldNotGetMimeType, connector.getSourceName(), contentId,
Expand All @@ -1050,12 +1050,12 @@ private void fireEntryCreated( ConnectorChangeSet connectorChangeSet,
Property lastModified = connector.propertyFactory().create(JcrLexicon.LAST_MODIFIED,
connector.lastModifiedTimeFor(file));
connectorChangeSet.propertyAdded(contentId, JcrNtLexicon.RESOURCE, Collections.<Name>emptySet(), contentId,
lastModified, queryable);
lastModified);
if (owner != null) {
// fire PROPERTY_ADDED for nt:file/jcr:content/jcr:lastModifiedBy
Property lastModifiedBy = connector.propertyFactory().create(JcrLexicon.LAST_MODIFIED_BY, owner);
connectorChangeSet.propertyAdded(contentId, JcrNtLexicon.RESOURCE, Collections.<Name>emptySet(), contentId,
lastModifiedBy, queryable);
lastModifiedBy);
}
}
}
Expand Down
20 changes: 16 additions & 4 deletions modeshape-jcr/src/main/java/org/modeshape/jcr/NodeTypes.java
Expand Up @@ -805,13 +805,25 @@ public NodeType getJcrNodeType( Name nodeTypeName ) {
}

/**
* Check if the node type with the given name is queryable or not, based on its node type definition.
* Check if the node type and mixin types are queryable or not.
*
* @param nodeTypeName a {@link Name}, never {@code null}
* @return {@code true} if the node type is queryable, {@code false} otherwise.
* @param mixinTypes the mixin type names; may not be null but may be empty
*
* @return {@code false} if at least one of the node types is not queryable, {@code true} otherwise
*/
public boolean isQueryable(Name nodeTypeName) {
return !nonQueryableNodeTypes.contains(nodeTypeName);
public boolean isQueryable(Name nodeTypeName, Set<Name> mixinTypes) {
if (nonQueryableNodeTypes.contains(nodeTypeName)) {
return false;
}
if (!mixinTypes.isEmpty()) {
for (Name mixinType : mixinTypes) {
if (nonQueryableNodeTypes.contains(mixinType)) {
return false;
}
}
}
return true;
}

/**
Expand Down
Expand Up @@ -424,7 +424,7 @@ protected void reindexContent( final String workspaceName,
final IndexWriter indexes ) {
assert indexes != null;
if (indexes.canBeSkipped()) return;
if (!node.isQueryable(cache)) {
if (node.isExcludedFromSearch(cache)) {
return;
}

Expand Down Expand Up @@ -483,7 +483,7 @@ protected void reindexContent( final String workspaceName,

// Look up the node and find the path ...
node = cache.getNode(key);
if (node == null || !node.isQueryable(cache)) {
if (node == null || node.isExcludedFromSearch(cache)) {
continue;
}
nodePath = paths.getPath(node);
Expand Down
Expand Up @@ -324,7 +324,7 @@ private void fireSequencingEvent( AbstractJcrNode sequencedNode,

sequencingChanges.nodeSequenced(sequencedNode.key(), sequencedNode.path(), primaryType, mixinTypes, outputNode.key(),
outputNode.path(), work.getOutputPath(), work.getUserId(), work.getSelectedPath(),
sequencerName, sequencedNode.node().isQueryable(outputSession.cache()));
sequencerName);
}
sequencingChanges.freeze(outputSession.getUserID(), null, context.getValueFactories().getDateFactory().create());
repository.changeBus().notify(sequencingChanges);
Expand All @@ -345,7 +345,7 @@ private void fireSequencingFailureEvent( AbstractJcrNode sequencedNode,
.journalId());
sequencingChanges.nodeSequencingFailure(sequencedNode.key(), sequencedNode.path(), primaryType, mixinTypes,
work.getOutputPath(), work.getUserId(), work.getSelectedPath(), sequencerName,
sequencedNode.node().isQueryable(inputSession.cache()), cause);
cause);
repository.changeBus().notify(sequencingChanges);
}

Expand Down
Expand Up @@ -51,7 +51,7 @@ public void initialize( SessionCache session,

// Create the "/jcr:system/jcr:versionStorage" node which we don't want to index
MutableCachedNode versionStorage = createNode(session, system, "jcr:versionStorage", JcrLexicon.VERSION_STORAGE, ModeShapeLexicon.VERSION_STORAGE);
versionStorage.setQueryable(false);
versionStorage.excludeFromSearch();

// Create the "/jcr:system/mode:namespaces" node ...
namespaces = createNode(session, system, "mode:namespaces", ModeShapeLexicon.NAMESPACES, ModeShapeLexicon.NAMESPACES);
Expand Down Expand Up @@ -79,11 +79,11 @@ public void initialize( SessionCache session,

// Create the "/jcr:system/mode:locks" node which we don't want to index
MutableCachedNode locks = createNode(session, system, "mode:locks", ModeShapeLexicon.LOCKS, ModeShapeLexicon.LOCKS);
locks.setQueryable(false);
locks.excludeFromSearch();

// Create the "/jcr:system/mode:indexes" node which we don't want to index
MutableCachedNode indexes = createNode(session, system, INDEXES_NODE_ID, ModeShapeLexicon.INDEXES, ModeShapeLexicon.INDEXES);
indexes.setQueryable(false);
indexes.excludeFromSearch();
}

protected MutableCachedNode createNode( SessionCache session,
Expand Down
Expand Up @@ -252,13 +252,13 @@ boolean isAtOrBelow( NodeCache cache,
Path path );

/**
* Determine if this node should be indexed and therefore available for querying. By default, every node is queryable, so only
* in certain cases can a node be made non-queryable.
* Determine if this node and *all* of its children should be taken into account when searching/indexing or not.
* A node which should be excluded from search will be completely ignored when indexing, together with all its children.
*
* @param cache the cache to which this node belongs, required in case this node needs to use the cache; may not be null
* @return {@code true} if the node should be indexed, {@code false} otherwise
*/
boolean isQueryable( NodeCache cache );
boolean isExcludedFromSearch( NodeCache cache );

/**
* Determine if there is an access control list for this node only, not taking into account any possible parents.
Expand Down
Expand Up @@ -409,11 +409,9 @@ public void deepClone( SessionCache cache,
public boolean hasOnlyChangesToAdditionalParents();

/**
* Sets a flag indicating if this node should be queryable or not.
*
* @param queryable a {@code boolean}.
* Sets a flag indicating if this node and anything below it should be excluded from all searches and indexing operations.
*/
public void setQueryable( boolean queryable );
public void excludeFromSearch();

/**
* Returns an object encapsulating all the different changes that this session node contains.
Expand Down
Expand Up @@ -40,13 +40,10 @@ public abstract class AbstractNodeChange extends Change {

protected final Path path;

private final boolean queryable;

protected AbstractNodeChange( NodeKey key,
Path path,
Name primaryType,
Set<Name> mixinTypes,
boolean queryable ) {
Set<Name> mixinTypes ) {
assert key != null;
assert path != null;

Expand All @@ -59,7 +56,6 @@ protected AbstractNodeChange( NodeKey key,
assert mixinTypes != null;
System.arraycopy(mixinTypes.toArray(new Name[0]), 0, types, 1, mixinTypes.size());
}
this.queryable = queryable;
}

/**
Expand Down Expand Up @@ -112,12 +108,4 @@ public boolean isType( Name nodeTypeName,
return nodeTypes.isTypeOrSubtype(types, nodeTypeName);
}

/**
* Return whether this node is queryable.
*
* @return true if this node is queryable, or false otherwise
*/
public boolean isQueryable() {
return queryable;
}
}
Expand Up @@ -34,9 +34,8 @@ protected AbstractPropertyChange( NodeKey key,
Name nodePrimaryType,
Set<Name> nodeMixinTypes,
Path nodePath,
Property property,
boolean queryable ) {
super(key, nodePath, nodePrimaryType, nodeMixinTypes, queryable);
Property property ) {
super(key, nodePath, nodePrimaryType, nodeMixinTypes);
this.property = property;
}

Expand Down
Expand Up @@ -39,12 +39,11 @@ protected AbstractSequencingChange( NodeKey sequencedNodeKey,
Path sequencedNodePath,
Name sequencedNodePrimaryType,
Set<Name> sequencedNodeMixinTypes,
boolean queryable,
String outputPath,
String userId,
String selectedPath,
String sequencerName ) {
super(sequencedNodeKey, sequencedNodePath, sequencedNodePrimaryType, sequencedNodeMixinTypes, queryable);
super(sequencedNodeKey, sequencedNodePath, sequencedNodePrimaryType, sequencedNodeMixinTypes);
assert outputPath != null;
assert userId != null;
assert selectedPath != null;
Expand Down

0 comments on commit 5c65b74

Please sign in to comment.