Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ repositories {
}
}

testCompile 'com.twcable.jackalope:jackalope:3.0.0'
testCompile 'com.twcable.jackalope:jackalope:3.1.0'
```

# LICENSE
Expand Down
5 changes: 5 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# RELEASE NOTES

## 3.1.0

* Implemented basic mixin support in NodeImpl
* Implemented basic NamePathResolver and NamespaceRegistry support in SessionImpl

## 3.0.0

Updated to support AEM 6.0, from AEM 5.6.1
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ dependencies {
runtime "ch.qos.logback:logback-classic:1.0.4"

testCompile "org.codehaus.groovy:groovy:2.3.6"
testCompile "org.spockframework:spock-core:0.7-groovy-2.0", {
testCompile "org.spockframework:spock-core:1.0-groovy-2.3", {
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
}
}
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# suppress inspection "UnusedProperty" for whole file
description = Provides a convenient way of stubbing out Sling and the JCR
group = com.twcable.jackalope
version = 3.0.0
version = 3.1.0-SNAPSHOT
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#Tue Feb 24 15:51:41 MST 2015
distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip
103 changes: 94 additions & 9 deletions src/main/java/com/twcable/jackalope/impl/jcr/NodeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import com.twcable.jackalope.impl.common.Paths;
import com.twcable.jackalope.impl.common.Values;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;

import javax.annotation.Nonnull;
import javax.jcr.AccessDeniedException;
Expand Down Expand Up @@ -45,18 +47,21 @@
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.version.ActivityViolationException;
import javax.jcr.version.Version;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;

import static java.util.Collections.singletonList;


/**
* Implementation of jcr Node interface.
Expand Down Expand Up @@ -336,43 +341,122 @@ public boolean hasProperties() throws RepositoryException {

@Override
public NodeType getPrimaryNodeType() throws RepositoryException {
return new NodeTypeImpl(getProperty("jcr:primaryType").getString());
return new NodeTypeImpl(primaryTypeProperty().getString());
}


private PropertyImpl primaryTypeProperty() throws RepositoryException {
return getOrCreateProperty(getJcrNameForQName(Property.JCR_PRIMARY_TYPE));
}


private PropertyImpl mixinProperty() throws RepositoryException {
return getOrCreateProperty(getJcrNameForQName(Property.JCR_MIXIN_TYPES));
}


/**
* Returns the declared mixin node types of this node.
* <p/>
* The default implementation uses the values of the
* <code>jcr:mixinTypes</code> property to look up the mixin node types
* from the {@link NodeTypeManager} of the current workspace.
*
* @return mixin node types
* @throws RepositoryException if an error occurs
*/
@Override
public NodeType[] getMixinNodeTypes() throws RepositoryException {
return new NodeType[0];
NodeTypeManager manager = getSession().getWorkspace().getNodeTypeManager();
Property property = mixinProperty();
Value[] values = property.getValues();
if (values == null) return new NodeType[0];
NodeType[] types = new NodeType[values.length];
for (int i = 0; i < values.length; i++) {
types[i] = manager.getNodeType(values[i].getString());
}
return types;
}


private String getJcrNameForQName(String name) throws RepositoryException {
return getJcrName(NameFactoryImpl.getInstance().create(name));
}


private String getJcrName(Name name) throws RepositoryException {
return session.getNamePathResolver().getJCRName(name);
}


@Override
public boolean isNodeType(String nodeTypeName) throws RepositoryException {
return getProperty("jcr:primaryType").getString().equals(nodeTypeName);
return primaryTypeProperty().getString().equals(nodeTypeName);
}


@Override
public void setPrimaryType(String nodeTypeName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
setProperty("jcr:primaryType", nodeTypeName);
setProperty(getJcrNameForQName(Property.JCR_PRIMARY_TYPE), nodeTypeName);
}


/**
* Very simple implementation of Mixin support: Does not check permissions, check for conflicts, etc.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check for conflicts == check for duplicates?

*/
@Override
public void addMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
//Not Implemented
Property mixinProperty = mixinProperty();
Value[] values = mixinProperty.getValues();
final Value[] newValues;
if (values == null) {
newValues = new Value[1];
newValues[0] = new ValueImpl(mixinName);
}
else {
newValues = new Value[values.length + 1];
System.arraycopy(values, 0, newValues, 0, values.length);
newValues[values.length] = new ValueImpl(mixinName);
}
mixinProperty.setValue(newValues);
session.changeItem(this);
}


@Override
public void removeMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException {
//Not Implemented
Property mixinProperty = mixinProperty();
Value[] values = mixinProperty.getValues();
if (values == null) {
throw new NoSuchNodeTypeException(mixinName);
}

boolean found = false;
Value[] newValues = new Value[values.length - 1];
for (int idx = 0, newIdx = 0; idx < values.length; ) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor : Could idx++ be in the for statement itself?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally avoid style comments, but I will admit that even in Java, I would be include to use a list for newValues and convert back to an array at the end.

I will also note that you don't need idx here so you could probably use a foreach here with newIdx being a counter initialized before the loop begins.

That would also allow you to ditch the found flag, you can just compare newIdx to the size of the original array.

Value value = values[idx];
if (value.getString().equals(mixinName)) {
idx++;
found = true;
}
else {
if (newIdx < newValues.length)
newValues[newIdx] = values[idx];
idx++;
newIdx++;
}
}

if (found) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't you be throwing a NoSuchNodeTypeException on !found?

mixinProperty.setValue(newValues);
session.changeItem(this);
}
}


@Override
public boolean canAddMixin(String mixinName) throws NoSuchNodeTypeException, RepositoryException {
return false;
return true;
}


Expand Down Expand Up @@ -426,7 +510,7 @@ public String getCorrespondingNodePath(String workspaceName) throws ItemNotFound

@Override
public NodeIterator getSharedSet() throws RepositoryException {
return new NodeIteratorImpl(Arrays.asList((Node)this)); //To change body of implemented methods use File | Settings | File Templates.
return new NodeIteratorImpl(singletonList((Node)this));
}


Expand Down Expand Up @@ -541,4 +625,5 @@ public void accept(ItemVisitor visitor) throws RepositoryException {
private PropertyImpl getOrCreateProperty(String name) throws RepositoryException {
return hasProperty(name) ? (PropertyImpl)getProperty(name) : new PropertyImpl(session, Paths.resolve(getPath(), name));
}

}
11 changes: 9 additions & 2 deletions src/main/java/com/twcable/jackalope/impl/jcr/NodeTypeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
/**
* Simple implementation of an {@link NodeType}
*/
@SuppressWarnings("unused")
public class NodeTypeImpl implements NodeType {
private final String nodeTypeName;
private boolean isMixin;


public NodeTypeImpl(String nodeTypeName) {
Expand Down Expand Up @@ -60,7 +62,7 @@ public NodeTypeIterator getDeclaredSubtypes() {

@Override
public boolean isNodeType(String nodeTypeName) {
return this.nodeTypeName.equals(nodeTypeName); //To change body of implemented methods use File | Settings | File Templates.
return this.nodeTypeName.equals(nodeTypeName);
}


Expand Down Expand Up @@ -136,9 +138,14 @@ public boolean isAbstract() {
}


public void setIsMixin(boolean isMixin) {
this.isMixin = isMixin;
}


@Override
public boolean isMixin() {
return false;
return this.isMixin;
}


Expand Down
Loading