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 }