View Javadoc

1   /*
2    * ====================
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4    * 
5    * Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved.     
6    * 
7    * The contents of this file are subject to the terms of the Common Development 
8    * and Distribution License("CDDL") (the "License").  You may not use this file 
9    * except in compliance with the License.
10   * 
11   * You can obtain a copy of the License at 
12   * http://IdentityConnectors.dev.java.net/legal/license.txt
13   * See the License for the specific language governing permissions and limitations 
14   * under the License. 
15   * 
16   * When distributing the Covered Code, include this CDDL Header Notice in each file
17   * and include the License file at identityconnectors/legal/license.txt.
18   * If applicable, add the following below this CDDL Header, with the fields 
19   * enclosed by brackets [] replaced by your own identifying information: 
20   * "Portions Copyrighted [year] [name of copyright owner]"
21   * ====================
22   */
23  /*
24   * Portions Copyrighted  2012 ForgeRock Inc.
25   */
26  package org.identityconnectors.framework.common.objects;
27  
28  import org.identityconnectors.common.CollectionUtil;
29  import org.identityconnectors.common.StringUtil;
30  import org.identityconnectors.framework.api.operations.CreateApiOp;
31  import org.identityconnectors.framework.api.operations.DeleteApiOp;
32  import org.identityconnectors.framework.api.operations.GetApiOp;
33  import org.identityconnectors.framework.api.operations.SearchApiOp;
34  import org.identityconnectors.framework.api.operations.UpdateApiOp;
35  
36  /**
37   * A single-valued attribute that represents the <i>unique identifier</i>
38   * of an object within the name-space of the target resource.
39   * If possible, this unique identifier also should be immutable.
40   * <p/>
41   * When an application creates an object on a target resource,
42   * the {@link CreateApiOp#create create} operation
43   * returns as its result the <code>Uid</code> of the created object.
44   * An application also can use the {@link SearchApiOp#search search} operation
45   * to discover the <code>Uid</code> value for an existing object.
46   * An application must use the <code>Uid</code> value to identify the object
47   * in any subsequent call to {@link GetApiOp#getObject get},
48   * {@link DeleteApiOp#delete delete}
49   * or {@link UpdateApiOp#update update} that object.
50   * See the documentation for {@link Name} for comparison.
51   * <p/>
52   * Ideally, the value of <code>Uid</code> would be a
53   * <i>Globally Unique IDentifier (GUID)</i>.
54   * However, not every target resource provides a globally unique
55   * and immutable identifier for each of its objects.
56   * For some connector implementations, therefore, the <code>Uid</code>
57   * value is only <i>locally</i> unique and may change when an object is modified.
58   * For instance, an LDAP directory service that lacks GUID might use
59   * <i>Distinguished Name (DN)</i> as the <code>Uid</code> for each object.
60   * A connector that represents each object as a row in a database table
61   * might use the value of the <i>primary key</i> as the <code>Uid</code> of an object.
62   * The fact that changing an object might change its <code>Uid</code>
63   * is the reason that {@link UpdateApiOp#update update} returns <code>Uid</code>.
64   * <p/>
65   * {@link Uid} by definition must be a single-valued attribute.
66   * Its value must always convert to a string,
67   * regardless of the underlying type of the native identifier on the target.
68   * The string value of any native id must be canonical.
69   * <p/>
70   * Uid is never allowed to appear in the {@link Schema},
71   * nor may Uid appear in the attribute set of a
72   * {@link CreateApiOp#create create} operation.
73   * This is because Uid is not a true attribute of an object, but
74   * rather a reference to that object.
75   * Uid extends {@link Attribute} only so that Uid can be searchable
76   * and compatible with the filter translators.
77   */
78  public final class Uid extends Attribute {
79  
80      public static final String NAME = AttributeUtil.createSpecialName("UID");
81  
82      private final String revision;
83  
84      public Uid(String value) {
85          super(NAME, CollectionUtil.<Object>newReadOnlyList(check(value)));
86          revision = null;
87      }
88  
89      public Uid(String value, String revision) {
90          super(NAME, CollectionUtil.<Object>newReadOnlyList(check(value)));
91          if (StringUtil.isBlank(revision)) {
92              final String ERR = "Revision value must not be blank!";
93              throw new IllegalArgumentException(ERR);
94          }
95          this.revision = revision;
96      }
97  
98      /**
99       * Throws an {@link IllegalArgumentException} if the value passed in blank.
100      */
101     private static String check(String value) {
102         if (StringUtil.isBlank(value)) {
103             final String ERR = "Uid value must not be blank!";
104             throw new IllegalArgumentException(ERR);
105         }
106         return value;
107     }
108 
109     /**
110      * Obtain a string representation of the value of this attribute,
111      * which value uniquely identifies a {@link ConnectorObject object}
112      * on the target resource.
113      *
114      * @return value that uniquely identifies an object.
115      */
116     public String getUidValue() {
117         return AttributeUtil.getStringValue(this);
118     }
119 
120     /**
121      * Return the string representation of the revision value of the
122      * <p/>
123      * The revision number specifies a given version ot the  {@link ConnectorObject object}
124      * identified by the {@link org.identityconnectors.framework.common.objects.Uid#getUidValue()}
125      *
126      * @return null if the connector does not support the MVCC and does not set this value
127      *         otherwise return the revision number of the object.
128      */
129     public String getRevision() {
130         return revision;
131     }
132 }