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 net.jcip.annotations.NotThreadSafe;
27  import org.modeshape.graph.ExecutionContext;
28  import org.modeshape.graph.Graph;
29  import org.modeshape.graph.NodeConflictBehavior;
30  import org.modeshape.graph.Graph.Batch;
31  import org.modeshape.graph.Graph.Create;
32  import org.modeshape.graph.property.Path;
33  import org.modeshape.graph.property.Property;
34  
35  /**
36   * A {@link Destination} that makes the changes to a graph via a {@link Batch}.
37   */
38  @NotThreadSafe
39  public class GraphBatchDestination implements Destination {
40      protected final Graph.Batch batch;
41      protected final boolean ignoreSubmit;
42  
43      /**
44       * Create a new instance that will use the specified batch. When {@link #submit()} is called, the batch will be
45       * {@link Batch#execute() executed}.
46       * 
47       * @param batch the batch
48       * @throws IllegalArgumentException if the batch is null
49       */
50      public GraphBatchDestination( Graph.Batch batch ) {
51          this(batch, false);
52      }
53  
54      /**
55       * Create a new instance that will use the specified batch. If {@code ignoreSubmit} is true, then {@link #submit()} does
56       * nothing (and the batch must be executed}; otherwise, {@link #submit()} immediately calls the {@link Batch#execute()
57       * executed}.
58       * 
59       * @param batch the batch
60       * @param ignoreSubmit true if the {@link #submit()} method should be ignored, or false otherwise
61       * @throws IllegalArgumentException if the batch is null
62       */
63      public GraphBatchDestination( Graph.Batch batch,
64                                    boolean ignoreSubmit ) {
65          assert batch != null;
66          this.batch = batch;
67          this.ignoreSubmit = ignoreSubmit;
68      }
69  
70      /**
71       * Return whether this instance is ignoring calls to {@link #submit()}.
72       * 
73       * @return ignoreSubmit
74       */
75      public boolean isSubmitIgnored() {
76          return ignoreSubmit;
77      }
78  
79      /**
80       * {@inheritDoc}
81       * 
82       * @see org.modeshape.graph.io.Destination#getExecutionContext()
83       */
84      public ExecutionContext getExecutionContext() {
85          return batch.getGraph().getContext();
86      }
87  
88      /**
89       * {@inheritDoc}
90       * 
91       * @see org.modeshape.graph.io.Destination#create(org.modeshape.graph.property.Path, Iterable)
92       */
93      public void create( Path path,
94                          Iterable<Property> properties ) {
95          assert properties != null;
96          Create<Batch> create = batch.create(path, properties);
97          assert create != null;
98          NodeConflictBehavior behavior = createBehaviorFor(path);
99          if (behavior != null) {
100             switch (behavior) {
101                 case APPEND:
102                     create.byAppending();
103                     break;
104                 case REPLACE:
105                     create.orReplace();
106                     break;
107                 case UPDATE:
108                     create.byAppending();
109                     break;
110                 case DO_NOT_REPLACE:
111                     create.byAppending();
112                     break;
113             }
114         }
115         create.and();
116     }
117 
118     /**
119      * {@inheritDoc}
120      * 
121      * @see org.modeshape.graph.io.Destination#create(org.modeshape.graph.property.Path, org.modeshape.graph.property.Property,
122      *      org.modeshape.graph.property.Property[])
123      */
124     public void create( Path path,
125                         Property firstProperty,
126                         Property... additionalProperties ) {
127         Create<Batch> create = null;
128         if (firstProperty == null) {
129             create = batch.create(path);
130         } else {
131             create = batch.create(path, firstProperty, additionalProperties);
132         }
133         assert create != null;
134         NodeConflictBehavior behavior = createBehaviorFor(path);
135         if (behavior != null) {
136             switch (behavior) {
137                 case APPEND:
138                     create.byAppending();
139                     break;
140                 case REPLACE:
141                     create.orReplace();
142                     break;
143                 case UPDATE:
144                     create.byAppending();
145                     break;
146                 case DO_NOT_REPLACE:
147                     create.byAppending();
148                     break;
149             }
150         }
151         create.and();
152     }
153 
154     /**
155      * {@inheritDoc}
156      * 
157      * @see org.modeshape.graph.io.Destination#setProperties(org.modeshape.graph.property.Path,
158      *      org.modeshape.graph.property.Property[])
159      */
160     public void setProperties( Path path,
161                                Property... properties ) {
162         if (properties == null) return;
163 
164         batch.set(properties).on(path);
165     }
166 
167     /**
168      * {@inheritDoc}
169      * 
170      * @see org.modeshape.graph.io.Destination#submit()
171      */
172     public void submit() {
173         // Execute only if we're not ignoring submits ...
174         if (!this.ignoreSubmit && !batch.hasExecuted()) batch.execute();
175     }
176 
177     /**
178      * Override this method in a subclass to control the {@link NodeConflictBehavior} that should be used when creating the node
179      * at the supplied path. By default, this method returns null.
180      * 
181      * @param path the path of the new node
182      * @return the conflict behavior, or null if {@link NodeConflictBehavior#UPDATE} should be used
183      */
184     protected NodeConflictBehavior createBehaviorFor( Path path ) {
185         return null;
186     }
187 }