KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > scriptella > driver > ldap > LdifScript


1 /*
2  * Copyright 2006-2007 The Scriptella Project Team.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package scriptella.driver.ldap;
17
18 import scriptella.core.EtlCancelledException;
19 import scriptella.driver.ldap.ldif.Entry;
20 import scriptella.driver.ldap.ldif.LdifParseException;
21 import scriptella.driver.ldap.ldif.LdifReader;
22 import scriptella.driver.ldap.ldif.SubstitutingLineReader;
23 import scriptella.spi.AbstractConnection;
24 import scriptella.spi.ParametersCallback;
25
26 import javax.naming.CompoundName JavaDoc;
27 import javax.naming.Name JavaDoc;
28 import javax.naming.NamingException JavaDoc;
29 import javax.naming.directory.Attributes JavaDoc;
30 import javax.naming.directory.DirContext JavaDoc;
31 import javax.naming.directory.ModificationItem JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.io.InputStream JavaDoc;
34 import java.io.Reader JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Properties JavaDoc;
37 import java.util.logging.Level JavaDoc;
38 import java.util.logging.Logger JavaDoc;
39
40 /**
41  * Executor for LDIF script.
42  *
43  * @author Fyodor Kupolov
44  * @version 1.0
45  */

46 public class LdifScript {
47     private static final Logger JavaDoc LOG = Logger.getLogger(LdifScript.class.getName());
48     //Parsing options for DN, TODO maybe replace with a DirCtx name parser?
49
static final Properties JavaDoc DN_SYNTAX = new Properties JavaDoc();
50
51     static {
52         DN_SYNTAX.setProperty("jndi.syntax.direction", "right_to_left");
53         DN_SYNTAX.setProperty("jndi.syntax.separator", ",");
54         DN_SYNTAX.setProperty("jndi.syntax.ignorecase", "true");
55         DN_SYNTAX.setProperty("jndi.syntax.trimblanks", "true");
56     }
57
58     private final LdapConnection connection;
59
60     public LdifScript(LdapConnection connection) {
61         if (connection == null) {
62             throw new IllegalArgumentException JavaDoc("Connection cannot be null");
63         }
64         this.connection = connection;
65     }
66
67
68     /**
69      * Executes an LDIF content from the specified reader.
70      *
71      * @param reader reader with LDIF content.
72      * @throws LdapProviderException if directory access failed.
73      */

74     public void execute(Reader reader, DirContext JavaDoc ctx, ParametersCallback parameters) throws LdapProviderException {
75         if (reader == null) {
76             throw new IllegalArgumentException JavaDoc("Reader cannot be null");
77         }
78         if (ctx == null) {
79             throw new IllegalArgumentException JavaDoc("DirContext cannot be null");
80         }
81         if (parameters == null) {
82             throw new IllegalArgumentException JavaDoc("Parameters cannot be null");
83         }
84         SubstitutingLineReader in = new SubstitutingLineReader(reader, parameters);
85         AbstractConnection.StatementCounter counter = connection.getStatementCounter();
86         try {
87             in.trackLines();
88             for (LdifIterator it = new LdifIterator(in); it.hasNext(); in.trackLines()) {
89                 EtlCancelledException.checkEtlCancelled();
90                 Entry e = it.next();
91                 if (isReadonly()) {
92                     LOG.info("Readonly Mode - "+e+" has been skipped.");
93                 } else {
94                     modify(ctx, e);
95                 }
96                 counter.statements++;
97             }
98         } catch (LdifParseException e) {
99             if (e.getErrorStatement() == null) {
100                 e.setErrorStatement(in.getTrackedLines());
101             }
102             throw e;
103         } catch (NamingException JavaDoc e) {
104             LdapProviderException ex = new LdapProviderException("Failed to execute LDIF entry", e);
105             ex.setErrorStatement(in.getTrackedLines());
106             throw ex;
107         }
108     }
109
110     /**
111      * Adds/modifies ctx using entry information.
112      *
113      * @param ctx directory context to use for change.
114      * @param e entry with change description.
115      * @throws NamingException if operation with directory failed.
116      */

117     static void modify(DirContext JavaDoc ctx, final Entry e) throws NamingException JavaDoc {
118         if (LOG.isLoggable(Level.FINE)) {
119             LOG.fine("Processing " + e);
120         }
121         Attributes JavaDoc atts = e.getAttributes();
122         final String JavaDoc rootDn = ctx.getNameInNamespace();
123         if (atts != null) { //If add entry
124
ctx.createSubcontext(getRelativeDN(rootDn, e.getDn()), e.getAttributes());
125         } else if (e.isChangeDelete()) {
126             ctx.destroySubcontext(getRelativeDN(rootDn, e.getDn()));
127         } else if (e.isChangeModDn() || e.isChangeModRdn()) {
128             Name JavaDoc newRdn;
129             if (e.getNewSuperior() != null) { //If new superior
130
newRdn = getRelativeDN(rootDn, e.getNewSuperior());
131             } else { //otherwise use DN as a base
132
newRdn = getRelativeDN(rootDn, e.getDn());
133                 newRdn.remove(newRdn.size() - 1);
134             }
135             newRdn.add(e.getNewRdn());
136             ctx.addToEnvironment("java.naming.ldap.deleteRDN", String.valueOf(e.isDeleteOldRdn()));
137             ctx.rename(getRelativeDN(rootDn, e.getDn()), newRdn);
138             ctx.removeFromEnvironment("java.naming.ldap.deleteRDN");//a better solution to use the previous value
139

140         } else {
141             List JavaDoc<ModificationItem JavaDoc> items = e.getModificationItems();
142             ctx.modifyAttributes(getRelativeDN(rootDn, e.getDn()),
143                     items.toArray(new ModificationItem JavaDoc[items.size()]));
144         }
145     }
146
147
148     /**
149      * @param rootDn root context DN.
150      * @param dn DN to compute a relative name. DN must starts with rootDn.
151      * @return name relative to a root context DN.
152      */

153     static Name JavaDoc getRelativeDN(final String JavaDoc rootDn, final String JavaDoc dn) throws NamingException JavaDoc {
154         CompoundName JavaDoc root = new CompoundName JavaDoc(rootDn, DN_SYNTAX);
155         CompoundName JavaDoc entry = new CompoundName JavaDoc(dn, DN_SYNTAX);
156         if (!entry.startsWith(root)) {
157             throw new NamingException JavaDoc("Dn " + dn + " is not from root DN " + rootDn);
158         }
159         return entry.getSuffix(root.size());
160     }
161
162     /**
163      * Accessor for testing purposes
164      */

165     protected Long JavaDoc getMaxFileLength() {
166         return connection == null ? null : connection.getMaxFileLength();
167     }
168
169     protected boolean isReadonly() {
170         return connection != null && connection.isReadonly();
171     }
172
173     private class LdifIterator extends LdifReader {
174
175         public LdifIterator(Reader in) {
176             super(in);
177             final Long JavaDoc maxFileLength = getMaxFileLength();
178             if (maxFileLength != null) {
179                 setSizeLimit(maxFileLength * 1024);
180             }
181         }
182
183         protected InputStream JavaDoc getUriStream(String JavaDoc uri) throws IOException JavaDoc {
184             return connection.getDriversContext().resolve(uri).openStream();
185         }
186     }
187
188 }
189
Popular Tags