From 71463feda7455ce67f5ba81c029a6f8b7a5a24f1 Mon Sep 17 00:00:00 2001
From: Philipp Marx
+ * Since binary storage and node storage most likely use different backend technologies two separate interfaces for
+ * these operations are provided.
+ *
+ * This interface is not only a partly {@code MicroKernel} but also provides a different layer of abstraction by
+ * converting the {@link String} parameters into higher level objects to ease the development for implementors of the
+ * {@code MicroKernel}.
+ *
+ * Since binary storage and node storage most likely use different backend technologies two separate interfaces for
+ * these operations are provided.
+ *
+ * This interface is not only a partly {@code MicroKernel} but also provides a different layer of abstraction by
+ * converting the {@link String} parameters into higher level objects to ease the development for implementors of the
+ * {@code MicroKernel}.
+ * BlobStore interface deals with all blob related operations of the {@link MicroKernel}.
+ *
+ *
+ * The implementation of this class contains the business logic to execute a command. + *
+ * + * @see Command Pattern + * @see Command + * + * @author JSOP diff of this commit. + * + * @return The {@link String} representing the diff. + */ + String getDiff(); + + /** + * Returns the {@link List} of {@link Instruction}s which were created from the diff. + * + * @see #getDiff() + * + * @return The {@link List} of {@link Instruction}s. + */ + List+ * Each operation is a concrete subinterface of {@code Instruction} and extending it by the specific properties of the + * operation. There is no exact 1 : 1 mapping between a {@code JSOP} operation and a subinterface, i.e. in {@code JSOP} + * there is one add operation for adding nodes and properties whereas there are two specific subinterfaces; one for + * adding a node and one for adding a property. + *
+ * + * @author "+" STRING ":" (ATOM | ARRAY) + */ + public interface AddPropertyInstruction extends Instruction { + + /** + * Returns the key of the property to add. + * + * @return The key. + */ + String getKey(); + + /** + * Returns the value of the property to add. + * + * @return The value. + */ + Object getValue(); + } + + /** + * The copy node operation => "*" STRING ":" STRING + */ + public interface CopyNodeInstruction extends Instruction { + + /** + * Returns the destination path. + * + * @return the destination path. + */ + String getDestPath(); + + /** + * Returns the source path. + * + * @return the source path. + */ + String getSourcePath(); + } + + /** + * The move node operation => ">" STRING ":" STRING + */ + public interface MoveNodeInstruction extends Instruction { + + /** + * Returns the destination path. + * + * @return the destination path. + */ + String getDestPath(); + + /** + * Returns the source path. + * + * @return the source path. + */ + String getSourcePath(); + } + + /** + * The remove node operation => "-" STRING + */ + public interface RemoveNodeInstruction extends Instruction { + } + + /** + * The set property operation => "^" STRING ":" ATOM | ARRAY + */ + public interface SetPropertyInstruction extends Instruction { + + /** + * Returns the key of the property to set. + * + * @return The key. + */ + String getKey(); + + /** + * Returns the value of the property to set. + * + * @return The value. + */ + Object getValue(); + } +} \ No newline at end of file diff --git a/oak-mongomk-api/src/main/java/org/apache/jackrabbit/mongomk/api/model/InstructionVisitor.java b/oak-mongomk-api/src/main/java/org/apache/jackrabbit/mongomk/api/model/InstructionVisitor.java new file mode 100644 index 0000000..c1b965c --- /dev/null +++ b/oak-mongomk-api/src/main/java/org/apache/jackrabbit/mongomk/api/model/InstructionVisitor.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.mongomk.api.model; + +import org.apache.jackrabbit.mongomk.api.model.Instruction.AddNodeInstruction; +import org.apache.jackrabbit.mongomk.api.model.Instruction.AddPropertyInstruction; +import org.apache.jackrabbit.mongomk.api.model.Instruction.CopyNodeInstruction; +import org.apache.jackrabbit.mongomk.api.model.Instruction.MoveNodeInstruction; +import org.apache.jackrabbit.mongomk.api.model.Instruction.RemoveNodeInstruction; +import org.apache.jackrabbit.mongomk.api.model.Instruction.SetPropertyInstruction; + +/** + * A Visitor to iterate through a list of + * {@code Instruction}s without the need to use {@code instanceof} on each item. + */ +public interface InstructionVisitor { + + /** + * Visits a {@code AddNodeInstruction}. + * + * @param instruction + * The instruction. + */ + void visit(AddNodeInstruction instruction); + + /** + * Visits a {@code AddPropertyInstruction}. + * + * @param instruction The instruction. + */ + void visit(AddPropertyInstruction instruction); + + /** + * Visits a {@code CopyNodeInstruction}. + * + * @param instruction The instruction. + */ + void visit(CopyNodeInstruction instruction); + + /** + * Visits a {@code MoveNodeInstruction}. + * + * @param instruction The instruction. + */ + void visit(MoveNodeInstruction instruction); + + /** + * Visits a {@code RemoveNodeInstruction}. + * + * @param instruction The instruction. + */ + void visit(RemoveNodeInstruction instruction); + + /** + * Visits a {@code SetPropertyInstruction}. + * + * @param instruction The instruction. + */ + void visit(SetPropertyInstruction instruction); +} \ No newline at end of file diff --git a/oak-mongomk-api/src/main/java/org/apache/jackrabbit/mongomk/api/model/Node.java b/oak-mongomk-api/src/main/java/org/apache/jackrabbit/mongomk/api/model/Node.java new file mode 100644 index 0000000..3265fa7 --- /dev/null +++ b/oak-mongomk-api/src/main/java/org/apache/jackrabbit/mongomk/api/model/Node.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.mongomk.api.model; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +/** + * A higher level object representing a node. + * + * @author + + + ++ * This class will transform and delegate to instances of {@link NodeStore} and {@link BlobStore}. + *
+ * + * @author 0 && nodeFilter != null && nodeFilter.getChildNodeFilter() != null) { + // Both an offset > 0 and a filter on node names have been specified... + throw new IllegalArgumentException("offset > 0 with child node filter"); + } + + try { + // FIXME [Mete] Should filter, offset, and maxChildNodes be handled in Mongo instead? + Node rootNode = nodeStore.getNodes(path, revisionId, depth, offset, maxChildNodes, filter); + if (rootNode == null) { + return null; + } + return JsonUtil.convertToJson(rootNode, depth, (int)offset, maxChildNodes, true, nodeFilter); + } catch (Exception e) { + throw new MicroKernelException(e); + } + } + + @Override + public String getRevisionHistory(long since, int maxEntries, String path) throws MicroKernelException { + return nodeStore.getRevisionHistory(since, maxEntries, path); + } + + @Override + public String merge(String branchRevisionId, String message) throws MicroKernelException { + throw new UnsupportedOperationException("Merge is currently not supported."); + } + + @Override + public boolean nodeExists(String path, String revisionId) throws MicroKernelException { + boolean exists = false; + + try { + String revId = null; + if (revisionId != null) { + revId = new String(revisionId); + } + + exists = nodeStore.nodeExists(path, revId); + } catch (Exception e) { + throw new MicroKernelException(e); + } + + return exists; + } + + @Override + public int read(String blobId, long pos, byte[] buff, int off, int length) throws MicroKernelException { + int totalBytes = -1; + + try { + totalBytes = blobStore.readBlob(blobId, pos, buff, off, length); + } catch (Exception e) { + throw new MicroKernelException(e); + } + + return totalBytes; + } + + @Override + public String waitForCommit(String oldHeadRevisionId, long timeout) throws MicroKernelException, + InterruptedException { + return nodeStore.waitForCommit(oldHeadRevisionId, timeout); + } + + @Override + public String write(InputStream in) throws MicroKernelException { + String blobId = null; + + try { + blobId = blobStore.writeBlob(in); + } catch (Exception e) { + throw new MicroKernelException(e); + } + + return blobId; + } +} \ No newline at end of file diff --git a/oak-mongomk-impl/src/main/java/org/apache/jackrabbit/mongomk/impl/NodeFilter.java b/oak-mongomk-impl/src/main/java/org/apache/jackrabbit/mongomk/impl/NodeFilter.java new file mode 100644 index 0000000..332204e --- /dev/null +++ b/oak-mongomk-impl/src/main/java/org/apache/jackrabbit/mongomk/impl/NodeFilter.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.mongomk.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.jackrabbit.mk.json.JsopTokenizer; +import org.apache.jackrabbit.mk.util.NameFilter; + +/** + * FIXME [Mete] Stolen from OAK. Should go away at some point when MongoMK becomes + * part of OAK. + */ +public class NodeFilter { + + NameFilter nodeFilter; + NameFilter propFilter; + + private NodeFilter(NameFilter nodeFilter, NameFilter propFilter) { + this.nodeFilter = nodeFilter; + this.propFilter = propFilter; + } + + static NodeFilter parse(String json) { + // parse json format filter + JsopTokenizer t = new JsopTokenizer(json); + t.read('{'); + + NameFilter nodeFilter = null, propFilter = null; + + do { + String type = t.readString(); + t.read(':'); + String[] globs = parseArray(t); + if (type.equals("nodes")) { + nodeFilter = new NameFilter(globs); + } else if (type.equals("properties")) { + propFilter = new NameFilter(globs); + } else { + throw new IllegalArgumentException("illegal filter format"); + } + } while (t.matches(',')); + t.read('}'); + + return new NodeFilter(nodeFilter, propFilter); + } + + private static String[] parseArray(JsopTokenizer t) { + List