View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.mitosis.operation;
21  
22  
23  import org.apache.directory.mitosis.common.CSN;
24  import org.apache.directory.mitosis.operation.support.EntryUtil;
25  import org.apache.directory.mitosis.store.ReplicationStore;
26  import org.apache.directory.server.core.CoreSession;
27  import org.apache.directory.server.core.entry.ClonedServerEntry;
28  import org.apache.directory.server.core.entry.ServerEntry;
29  import org.apache.directory.server.core.filtering.EntryFilteringCursor;
30  import org.apache.directory.server.core.interceptor.context.AddOperationContext;
31  import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
32  import org.apache.directory.server.core.interceptor.context.ListOperationContext;
33  import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
34  import org.apache.directory.server.core.partition.PartitionNexus;
35  import org.apache.directory.server.schema.registries.Registries;
36  import org.apache.directory.shared.ldap.entry.Entry;
37  import org.apache.directory.shared.ldap.name.LdapDN;
38  
39  
40  /**
41   * An {@link Operation} that adds a new entry.
42   *
43   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
44   */
45  public class AddEntryOperation extends Operation
46  {
47      /**
48       * Declares the Serial Version Uid.
49       *
50       * @see <a
51       *      href="http://c2.com/cgi/wiki?AlwaysDeclareSerialVersionUid">Always
52       *      Declare Serial Version Uid</a>
53       */
54      private static final long serialVersionUID = 2294492811671880570L;
55  
56      /** The entry to add */
57      private Entry entry;
58  
59  
60      /**
61       * Creates a new operation that adds the specified entry. This 
62       * constructor will not be visible out of this package, as it is 
63       * only used for the deserialization process.
64       * 
65       * @param registries the registries instance
66       */
67      public AddEntryOperation( Registries registries )
68      {
69          super( registries, OperationType.ADD_ENTRY );
70      }
71      
72      
73      /**
74       * Creates a new instance.
75       * 
76       * @param entry an entry
77       */
78      public AddEntryOperation( Registries registries, CSN csn, ServerEntry entry )
79      {
80          super( registries, OperationType.ADD_ENTRY, csn );
81  
82          assert entry != null;
83  
84          this.entry = entry;
85      }
86  
87  
88      /**
89       * Inject the entry into the local server
90       * 
91       * @param nexus the local partition to update
92       * @param store not used... Just for inheritence sake.
93       * @param coreSession the current session
94       */
95      protected void execute0( PartitionNexus nexus, ReplicationStore store, CoreSession coreSession )
96          throws Exception
97      {
98          if ( ! EntryUtil.isEntryUpdatable( coreSession, entry.getDn(), getCSN() ) )
99          {
100             return;
101         }
102         
103         EntryUtil.createGlueEntries( coreSession, entry.getDn(), false );
104 
105         // Replace the entry if an entry with the same name exists.
106         if ( nexus.lookup( new LookupOperationContext( coreSession, entry.getDn() ) ) != null )
107         {
108             recursiveDelete( nexus, entry.getDn(), coreSession );
109         }
110 
111         nexus.add( new AddOperationContext( coreSession, (ServerEntry)entry ) );
112     }
113 
114 
115     /**
116      * 
117      * TODO recursiveDelete.
118      *
119      * @param nexus
120      * @param normalizedName
121      * @param coreSession
122      * @throws Exception
123      */
124     @SuppressWarnings("unchecked")
125     private void recursiveDelete( PartitionNexus nexus, LdapDN normalizedName, CoreSession coreSession )
126         throws Exception
127     {
128         EntryFilteringCursor cursor = nexus.list( new ListOperationContext( coreSession, normalizedName ) );
129         
130         if ( !cursor.available() )
131         {
132             nexus.delete( new DeleteOperationContext( coreSession, normalizedName ) );
133             return;
134         }
135 
136         Registries registries = coreSession.getDirectoryService().getRegistries();
137         while ( cursor.next() )
138         {
139             ClonedServerEntry sr = cursor.get();
140             LdapDN dn = sr.getDn();
141             dn.normalize( registries.getAttributeTypeRegistry().getNormalizerMapping() );
142             recursiveDelete( nexus, dn, coreSession );
143         }
144         
145         nexus.delete( new DeleteOperationContext( coreSession, normalizedName ) );
146     }
147 
148     
149     /**
150      * Set the Entry to add into this AddEntry instance.
151      *
152      * @param entry the entry to add
153      */
154     public void setEntry( Entry entry )
155     {
156         this.entry = entry;
157     }
158 
159 
160     /**
161      * @return the operation's entry
162      */
163     public Entry getEntry()
164     {
165         return entry;
166     }
167 
168     
169     /**
170      * @see Object#toString()
171      */
172     public String toString()
173     {
174         return super.toString() + ": [" + entry.getDn() + "].new( " + entry + " )";
175     }
176 }