001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *      Copyright 2012-2014 ForgeRock AS
024 *
025 */
026
027package org.forgerock.opendj.examples;
028
029import java.io.IOException;
030import java.util.Calendar;
031import java.util.Set;
032
033import org.forgerock.opendj.ldap.AttributeDescription;
034import org.forgerock.opendj.ldap.Connection;
035import org.forgerock.opendj.ldap.DN;
036import org.forgerock.opendj.ldap.Entry;
037import org.forgerock.opendj.ldap.LdapException;
038import org.forgerock.opendj.ldap.LDAPConnectionFactory;
039import org.forgerock.opendj.ldap.LinkedHashMapEntry;
040import org.forgerock.opendj.ldap.ModificationType;
041import org.forgerock.opendj.ldap.ResultCode;
042import org.forgerock.opendj.ldap.requests.ModifyRequest;
043import org.forgerock.opendj.ldap.requests.Requests;
044import org.forgerock.opendj.ldap.responses.SearchResultEntry;
045import org.forgerock.opendj.ldap.schema.Schema;
046import org.forgerock.opendj.ldif.LDIFEntryWriter;
047
048/**
049 * This command-line client demonstrates parsing entry attribute values to
050 * objects. The client takes as arguments the host and port for the directory
051 * server, and expects to find the entries and access control instructions as
052 * defined in <a
053 * href="http://opendj.forgerock.org/Example.ldif">Example.ldif</a>.
054 */
055public final class ParseAttributes {
056
057    /**
058     * Connect to the server, and then try to use some LDAP controls.
059     *
060     * @param args
061     *            The command line arguments: host, port
062     */
063    public static void main(final String[] args) {
064        if (args.length != 2) {
065            System.err.println("Usage: host port");
066            System.err.println("For example: localhost 1389");
067            System.exit(1);
068        }
069        final String host = args[0];
070        final int port = Integer.parseInt(args[1]);
071
072        // --- JCite ---
073        final LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port);
074        Connection connection = null;
075        try {
076            connection = factory.getConnection();
077
078            // Use Kirsten Vaughan's credentials and her entry.
079            String name = "uid=kvaughan,ou=People,dc=example,dc=com";
080            char[] password = "bribery".toCharArray();
081            connection.bind(name, password);
082
083            // Make sure we have a timestamp to play with.
084            updateEntry(connection, name, "description");
085
086            // Read Kirsten's entry.
087            final SearchResultEntry entry = connection.readEntry(name,
088                    "cn", "objectClass", "hasSubordinates", "numSubordinates",
089                    "isMemberOf", "modifyTimestamp");
090
091            // Get the entry DN and some attribute values as objects.
092            DN dn = entry.getName();
093
094            Set<String> cn = entry.parseAttribute("cn").asSetOfString("");
095            Set<AttributeDescription> objectClasses =
096                    entry.parseAttribute("objectClass").asSetOfAttributeDescription();
097            boolean hasChildren = entry.parseAttribute("hasSubordinates").asBoolean();
098            int numChildren = entry.parseAttribute("numSubordinates").asInteger(0);
099            Set<DN> groups = entry
100                    .parseAttribute("isMemberOf")
101                    .usingSchema(Schema.getDefaultSchema()).asSetOfDN();
102            Calendar timestamp = entry
103                    .parseAttribute("modifyTimestamp")
104                    .asGeneralizedTime().toCalendar();
105
106            // Do something with the objects.
107            // ...
108
109            // This example simply dumps what was obtained.
110            entry.setName(dn);
111            Entry newEntry = new LinkedHashMapEntry(name)
112                .addAttribute("cn", cn.toArray())
113                .addAttribute("objectClass", objectClasses.toArray())
114                .addAttribute("hasChildren", hasChildren)
115                .addAttribute("numChildren", numChildren)
116                .addAttribute("groups", groups.toArray())
117                .addAttribute("timestamp", timestamp.getTimeInMillis());
118
119            final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
120            writer.writeEntry(newEntry);
121            writer.close();
122        } catch (final LdapException e) {
123            System.err.println(e.getMessage());
124            System.exit(e.getResult().getResultCode().intValue());
125            return;
126        } catch (IOException e) {
127            System.err.println(e.getMessage());
128            System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
129        } finally {
130            if (connection != null) {
131                connection.close();
132            }
133        }
134        // --- JCite ---
135    }
136
137    /**
138     * Update and entry to generate a time stamp.
139     *
140     * @param connection
141     *            Connection to the directory server with rights to perform a
142     *            modification on the entry.
143     * @param name
144     *            DN of the entry to modify.
145     * @param attributeDescription
146     *            Attribute to modify. Must take a String value.
147     * @throws LdapException
148     *             Modify failed.
149     */
150    private static void updateEntry(final Connection connection, final String name,
151            final String attributeDescription) throws LdapException {
152        ModifyRequest request = Requests.newModifyRequest(name)
153                .addModification(ModificationType.REPLACE, attributeDescription, "This is a String.");
154        connection.modify(request);
155    }
156
157    /**
158     * Constructor not used.
159     */
160    private ParseAttributes() {
161        // Not used.
162    }
163}