Skip to content

Commit

Permalink
started API and implementation for user friendly access to node type …
Browse files Browse the repository at this point in the history
…definition and manipulation #1
  • Loading branch information
hpoul authored and bigbear3001 committed Feb 2, 2014
1 parent d150d11 commit 4c670f9
Show file tree
Hide file tree
Showing 14 changed files with 316 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.Collections;

import javax.annotation.Nonnull;

import com.dc2f.dstore.hierachynodestore.impl.WorkingTreeImpl;
import com.dc2f.dstore.storage.Property;
import com.dc2f.dstore.storage.StorageBackend;
Expand All @@ -15,9 +17,9 @@
public class HierarchicalNodeStore {
private StorageBackend storageBackend;

private final static String ROOT_COMMIT_ID = "rootCommitId";
private final static String ROOT_NODE_NAME = "";
private final static String MASTER_BRANCH_NAME = "master";
private final static @Nonnull String ROOT_COMMIT_ID = "rootCommitId";
private final static @Nonnull String ROOT_NODE_NAME = "";
private final static @Nonnull String MASTER_BRANCH_NAME = "master";


public HierarchicalNodeStore(StorageBackend storageBackend) {
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/com/dc2f/dstore/hierachynodestore/WorkingTree.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package com.dc2f.dstore.hierachynodestore;

import javax.annotation.Nonnull;

import com.dc2f.dstore.hierachynodestore.nodetype.NodeTypeAccessor;


public interface WorkingTree {
WorkingTreeNode getRootNode();
@Nonnull WorkingTreeNode getRootNode();

Commit commit(String message);
@Nonnull Commit commit(String message);

@Nonnull NodeTypeAccessor getNodeTypeAccessor();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,25 @@ public interface WorkingTreeNode {
* @return the created child for this node
*/
@Nonnull
WorkingTreeNode addChild(String childName);
WorkingTreeNode addChild(@Nonnull String childName);

@Nonnull
WorkingTreeNode addChild();


@Nonnull
Iterable<WorkingTreeNode> getChildren();
int getChildrenCount();

@Nullable
Property getProperty(String name);
Property getProperty(@Nonnull String name);

void setProperty(@Nonnull String name, @Nonnull Property value);

@Nonnull
Map<String, Property> getProperties();

Iterable<WorkingTreeNode> getChildrenByProperty(String propertyName, Object value);
Iterable<WorkingTreeNode> getChildrenByProperty(@Nonnull String propertyName, Object value);

/**
* @return the storage id of the node. might return null, if it was not yet committed.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.dc2f.dstore.hierachynodestore.exception;

/**
* generic exception from your node store.
*/
public class NodeStoreException extends RuntimeException {
private static final long serialVersionUID = 1L;


public NodeStoreException(String message) {
this(message, null);
}
public NodeStoreException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
import java.util.Map;
import java.util.Set;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import com.dc2f.dstore.hierachynodestore.Commit;
import com.dc2f.dstore.hierachynodestore.HierarchicalNodeStore;
import com.dc2f.dstore.hierachynodestore.WorkingTree;
import com.dc2f.dstore.hierachynodestore.WorkingTreeNode;
import com.dc2f.dstore.hierachynodestore.impl.nodetype.NodeTypeAccessorImpl;
import com.dc2f.dstore.hierachynodestore.nodetype.NodeTypeAccessor;
import com.dc2f.dstore.storage.MutableStoredFlatNode;
import com.dc2f.dstore.storage.Property;
import com.dc2f.dstore.storage.StorageBackend;
Expand All @@ -20,14 +25,19 @@

public class WorkingTreeImpl implements WorkingTree {

private HierarchicalNodeStore hierarchicalNodeStore;
/**
* Reference back to the hierarchical node store in case we need it(?)
*/
@SuppressWarnings("unused")
private @Nonnull HierarchicalNodeStore hierarchicalNodeStore;
private StoredCommit headCommit;
private String branchName;
private @Nullable NodeTypeAccessor nodeTypeAccessor;
StorageBackend storageBackend;
Map<StorageId, WorkingTreeNodeImpl> loadedNodes = new HashMap<>();
private List<WorkingTreeNodeImpl> changedNodes = new ArrayList<>();

public WorkingTreeImpl(HierarchicalNodeStore hierarchicalNodeStore,
public WorkingTreeImpl(@Nonnull HierarchicalNodeStore hierarchicalNodeStore,
StorageBackend storageBackend, StoredCommit headCommit, String branchName) {
this.hierarchicalNodeStore = hierarchicalNodeStore;
this.storageBackend = storageBackend;
Expand All @@ -36,13 +46,13 @@ public WorkingTreeImpl(HierarchicalNodeStore hierarchicalNodeStore,
}

@Override
public WorkingTreeNode getRootNode() {
public @Nonnull WorkingTreeNode getRootNode() {
StorageId rootNodeId = headCommit.getRootNode();
return getNodeByStorageId(rootNodeId, null);
// return new WorkingTreeNodeImpl(this, storageBackend.readNode(rootNodeId));
}

public WorkingTreeNode getNodeByStorageId(StorageId nodeStorageId, WorkingTreeNodeImpl parentNode) {
public @Nonnull WorkingTreeNode getNodeByStorageId(StorageId nodeStorageId, WorkingTreeNodeImpl parentNode) {
// TODO shouldn't we add caching right here?
WorkingTreeNodeImpl ret = loadedNodes.get(nodeStorageId);
if (ret == null) {
Expand All @@ -61,7 +71,7 @@ public void notifyNodeChanged(WorkingTreeNodeImpl workingTreeNodeImpl) {
}

@Override
public Commit commit(String message) {
public @Nonnull Commit commit(String message) {
if (message == null) {
message = "";
}
Expand Down Expand Up @@ -191,5 +201,15 @@ private Set<WorkingTreeNodeImpl> findNodesToUpdate() {
return toUpdate;
}

@Override
@Nonnull
public NodeTypeAccessor getNodeTypeAccessor() {
NodeTypeAccessor ret = nodeTypeAccessor;
if (ret == null) {
nodeTypeAccessor = ret = new NodeTypeAccessorImpl(this);
}
return ret;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public WorkingTreeNodeImpl(@Nonnull WorkingTreeImpl workingTreeImpl,
}

@Override
public Iterable<WorkingTreeNode> getChildrenByProperty(String propertyName, Object value) {
public Iterable<WorkingTreeNode> getChildrenByProperty(@Nonnull String propertyName, Object value) {
ChildQueryAdapter queryAdapter = workingTreeImpl.storageBackend.getAdapter(ChildQueryAdapter.class);

StorageId storageId = this.getStorageId();
Expand Down Expand Up @@ -124,9 +124,17 @@ public Iterable<WorkingTreeNode> getChildrenByProperty(String propertyName, Obje
// }

@Override @Nonnull
public WorkingTreeNode addChild(String childName) {
WorkingTreeNodeImpl child = new WorkingTreeNodeImpl(workingTreeImpl, null, this);
public WorkingTreeNode addChild(@Nonnull String childName) {
WorkingTreeNode child = addChild();
child.setProperty(Property.PROPERTY_NAME, new Property(childName));

return child;
}

@Override
@Nonnull
public WorkingTreeNode addChild() {
WorkingTreeNodeImpl child = new WorkingTreeNodeImpl(workingTreeImpl, null, this);
child.isNew = true;
workingTreeImpl.loadedNodes.put(child.getStorageId(), child);
if (createdChildren == null) {
Expand Down Expand Up @@ -228,7 +236,7 @@ public int getChildrenCount() {
}

@Nullable
public Property getProperty(String propertyName) {
public Property getProperty(@Nonnull String propertyName) {
return loadProperties().get(propertyName);
// Map<String, Property> properties = workingTreeImpl.storageBackend.readProperties(storedNode.getProperties());
// return properties.get(propertyName);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.dc2f.dstore.hierachynodestore.impl.nodetype;

import java.util.Collection;

import javax.annotation.Nonnull;

import com.dc2f.dstore.hierachynodestore.impl.WorkingTreeImpl;
import com.dc2f.dstore.hierachynodestore.nodetype.NodeTypeAccessor;
import com.dc2f.dstore.hierachynodestore.nodetype.NodeTypeDefinition;


public class NodeTypeAccessorImpl implements NodeTypeAccessor {
@SuppressWarnings("unused")
private @Nonnull WorkingTreeImpl workingTreeImpl;

public NodeTypeAccessorImpl(@Nonnull WorkingTreeImpl workingTreeImpl) {
this.workingTreeImpl = workingTreeImpl;
}

@Override
public @Nonnull Collection<NodeTypeDefinition> listNodeTypeDefinitions() {
throw new UnsupportedOperationException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.dc2f.dstore.hierachynodestore.impl.nodetype;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import javax.annotation.Nonnull;

import com.dc2f.dstore.hierachynodestore.WorkingTreeNode;
import com.dc2f.dstore.hierachynodestore.nodetype.NodeTypeDefinition;
import com.dc2f.dstore.hierachynodestore.nodetype.PropertyDefinition;
import com.dc2f.dstore.storage.Property;

import static com.dc2f.utils.NullUtils.assertNotNull;

public class NodeTypeDefinitionImpl implements NodeTypeDefinition {
public static final @Nonnull String PROPERTY_NAME = ":name";

private @Nonnull WorkingTreeNode node;

public NodeTypeDefinitionImpl(@Nonnull WorkingTreeNode node) {
// TODO assert node type?
this.node = node;
}

@Override
@Nonnull
public Collection<PropertyDefinition> listPropertyDefinitions() {
List<PropertyDefinition> ret = new ArrayList<>();
for (WorkingTreeNode child : node.getChildren()) {
ret.add(new PropertyDefinitionImpl(assertNotNull(child)));
}
return assertNotNull(Collections.unmodifiableCollection(ret));
}

@Override
@Nonnull
public PropertyDefinition addPropertyDefinition(@Nonnull String name) {
WorkingTreeNode propertyNode = node.addChild();
propertyNode.setProperty(PROPERTY_NAME, new Property(name));
return new PropertyDefinitionImpl(propertyNode);
}

@Override
@Nonnull
public Collection<NodeTypeDefinition> listAllowedChildNodeTypes() {
// FIXME implement me :)
return new ArrayList<>();
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.dc2f.dstore.hierachynodestore.impl.nodetype;

import javax.annotation.Nonnull;

import com.dc2f.dstore.hierachynodestore.WorkingTreeNode;
import com.dc2f.dstore.hierachynodestore.exception.NodeStoreException;
import com.dc2f.dstore.hierachynodestore.nodetype.PropertyDefinition;
import com.dc2f.dstore.storage.Property;
import com.dc2f.dstore.storage.Property.PropertyType;

import static com.dc2f.utils.NullUtils.assertNotNull;

public class PropertyDefinitionImpl implements PropertyDefinition {
public static final @Nonnull String PROPERTY_NAME = NodeTypeDefinitionImpl.PROPERTY_NAME;
public static final @Nonnull String PROPERTY_TYPE = ":type";
public static final @Nonnull String PROPERTY_REQUIRED = ":required";
public static final @Nonnull String PROPERTY_INDEXED = ":indexed";

private WorkingTreeNode node;

public PropertyDefinitionImpl(@Nonnull WorkingTreeNode node) {
this.node = node;
}

@Override
@Nonnull
public String getName() {
// a property definition must always have a name..
return assertNotNull(node.getProperty(PROPERTY_NAME)).getString();
}

@Override
@Nonnull
public PropertyType getType() {
// property definition must always have a type.
Property typeProperty = assertNotNull(node.getProperty(PROPERTY_TYPE));
PropertyType propertyType = PropertyType.valueOf(typeProperty.getString());
if (propertyType == null) {
throw new NodeStoreException("Illegal property type {" + typeProperty.getString() + "}");
}
return propertyType;
}

@Override
public void setRequired(boolean isRequired) {
node.setProperty(PROPERTY_REQUIRED, new Property(new Boolean(isRequired)));
}

@Override
public boolean isRequired() {
Property requiredProperty = node.getProperty(PROPERTY_REQUIRED);
if (requiredProperty == null) {
return false;
}
return requiredProperty.getBoolean();
}

@Override
public void setIndexed(boolean isIndexed) {
node.setProperty(PROPERTY_INDEXED, new Property(new Boolean(isIndexed)));
}

@Override
public boolean isIndexed() {
Property indexedProperty = node.getProperty(PROPERTY_INDEXED);
if (indexedProperty == null) {
return false;
}
return indexedProperty.getBoolean();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.dc2f.dstore.hierachynodestore.nodetype;

import java.util.Collection;

import javax.annotation.Nonnull;

import com.dc2f.dstore.hierachynodestore.WorkingTree;

/**
* Convenience interface to access node types in a working tree of a repository. Allows reflection and editing
* of node types.
*
*
* @see WorkingTree#getNodeTypeAccessor()
*/
public interface NodeTypeAccessor {
/**
* find all node type definitions in the current working tree and return them.
* TODO: really all, or just those within /:nodetypes/ ??
* @return list of all node type definnitions.
*/
@Nonnull Collection<NodeTypeDefinition> listNodeTypeDefinitions();


}
Loading

0 comments on commit 4c670f9

Please sign in to comment.