View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors.
8    *
9    * Unless otherwise indicated, all code in ModeShape is licensed
10   * to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   * 
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.graph.io;
25  
26  import java.util.List;
27  import net.jcip.annotations.NotThreadSafe;
28  import org.modeshape.graph.ExecutionContext;
29  import org.modeshape.graph.Graph;
30  import org.modeshape.graph.NodeConflictBehavior;
31  import org.modeshape.graph.Graph.Batch;
32  import org.modeshape.graph.Graph.Create;
33  import org.modeshape.graph.property.Path;
34  import org.modeshape.graph.property.Property;
35  
36  /**
37   * A {@link Destination} that makes the changes to a graph via a {@link Batch}.
38   */
39  @NotThreadSafe
40  public class GraphBatchDestination implements Destination {
41      protected final Graph.Batch batch;
42      protected final boolean ignoreSubmit;
43  
44      /**
45       * Create a new instance that will use the specified batch. When {@link #submit()} is called, the batch will be
46       * {@link Batch#execute() executed}.
47       * 
48       * @param batch the batch
49       * @throws IllegalArgumentException if the batch is null
50       */
51      public GraphBatchDestination( Graph.Batch batch ) {
52          this(batch, false);
53      }
54  
55      /**
56       * Create a new instance that will use the specified batch. If {@code ignoreSubmit} is true, then {@link #submit()} does
57       * nothing (and the batch must be executed}; otherwise, {@link #submit()} immediately calls the {@link Batch#execute()
58       * executed}.
59       * 
60       * @param batch the batch
61       * @param ignoreSubmit true if the {@link #submit()} method should be ignored, or false otherwise
62       * @throws IllegalArgumentException if the batch is null
63       */
64      public GraphBatchDestination( Graph.Batch batch,
65                                    boolean ignoreSubmit ) {
66          assert batch != null;
67          this.batch = batch;
68          this.ignoreSubmit = ignoreSubmit;
69      }
70  
71      /**
72       * Return whether this instance is ignoring calls to {@link #submit()}.
73       * 
74       * @return ignoreSubmit
75       */
76      public boolean isSubmitIgnored() {
77          return ignoreSubmit;
78      }
79  
80      /**
81       * {@inheritDoc}
82       * 
83       * @see org.modeshape.graph.io.Destination#getExecutionContext()
84       */
85      public ExecutionContext getExecutionContext() {
86          return batch.getGraph().getContext();
87      }
88  
89      /**
90       * {@inheritDoc}
91       * 
92       * @see org.modeshape.graph.io.Destination#create(org.modeshape.graph.property.Path, java.util.List)
93       */
94      public void create( Path path,
95                          List<Property> properties ) {
96          assert properties != null;
97          Create<Batch> create = null;
98          if (properties.isEmpty()) {
99              create = batch.create(path);
100         } else {
101             create = batch.create(path, properties);
102         }
103         assert create != null;
104         NodeConflictBehavior behavior = createBehaviorFor(path);
105         if (behavior != null) {
106             switch (behavior) {
107                 case APPEND:
108                     create.byAppending();
109                     break;
110                 case REPLACE:
111                     create.orReplace();
112                     break;
113                 case UPDATE:
114                     create.byAppending();
115                     break;
116                 case DO_NOT_REPLACE:
117                     create.byAppending();
118                     break;
119             }
120         }
121         create.and();
122     }
123 
124     /**
125      * {@inheritDoc}
126      * 
127      * @see org.modeshape.graph.io.Destination#create(org.modeshape.graph.property.Path, org.modeshape.graph.property.Property,
128      *      org.modeshape.graph.property.Property[])
129      */
130     public void create( Path path,
131                         Property firstProperty,
132                         Property... additionalProperties ) {
133         Create<Batch> create = null;
134         if (firstProperty == null) {
135             create = batch.create(path);
136         } else {
137             create = batch.create(path, firstProperty, additionalProperties);
138         }
139         assert create != null;
140         NodeConflictBehavior behavior = createBehaviorFor(path);
141         if (behavior != null) {
142             switch (behavior) {
143                 case APPEND:
144                     create.byAppending();
145                     break;
146                 case REPLACE:
147                     create.orReplace();
148                     break;
149                 case UPDATE:
150                     create.byAppending();
151                     break;
152                 case DO_NOT_REPLACE:
153                     create.byAppending();
154                     break;
155             }
156         }
157         create.and();
158     }
159 
160     /**
161      * {@inheritDoc}
162      * 
163      * @see org.modeshape.graph.io.Destination#setProperties(org.modeshape.graph.property.Path,
164      *      org.modeshape.graph.property.Property[])
165      */
166     public void setProperties( Path path,
167                                Property... properties ) {
168         if (properties == null) return;
169 
170         batch.set(properties).on(path);
171     }
172 
173     /**
174      * {@inheritDoc}
175      * 
176      * @see org.modeshape.graph.io.Destination#submit()
177      */
178     public void submit() {
179         // Execute only if we're not ignoring submits ...
180         if (!this.ignoreSubmit && !batch.hasExecuted()) batch.execute();
181     }
182 
183     /**
184      * Override this method in a subclass to control the {@link NodeConflictBehavior} that should be used when creating the node
185      * at the supplied path. By default, this method returns null.
186      * 
187      * @param path the path of the new node
188      * @return the conflict behavior, or null if {@link NodeConflictBehavior#UPDATE} should be used
189      */
190     protected NodeConflictBehavior createBehaviorFor( Path path ) {
191         return null;
192     }
193 }