001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.util;
020:
021: import java.security.AccessController;
022:
023: import org.apache.openjpa.conf.OpenJPAConfiguration;
024: import org.apache.openjpa.lib.util.J2DoPrivHelper;
025: import org.apache.openjpa.lib.util.Localizer;
026: import serp.util.Numbers;
027:
028: /**
029: * Datastore identity type. Implementations may choose to use this type,
030: * or choose to use their own datastore identity values.
031: *
032: * @author Abe White
033: */
034: public final class Id extends OpenJPAId {
035:
036: private static final Localizer _loc = Localizer
037: .forPackage(Id.class);
038:
039: private final long _id;
040:
041: /**
042: * Create an id from the given type and value; the value might be an
043: * id instnace, a stringified id, or a primary key value.
044: */
045: public static Id newInstance(Class cls, Object val) {
046: if (val instanceof Id)
047: return (Id) val;
048: if (val instanceof String)
049: return new Id(cls, (String) val);
050: if (val instanceof Number)
051: return new Id(cls, ((Number) val).longValue());
052: if (val == null)
053: return new Id(cls, 0L);
054: throw new UserException(_loc.get("unknown-oid", cls, val, val
055: .getClass()));
056: }
057:
058: /**
059: * Create an id from the result of a {@link #toString} call on another
060: * instance.
061: */
062: public Id(String str) {
063: this (str, (ClassLoader) null);
064: }
065:
066: /**
067: * Create an id from the result of an {@link #toString} call on another
068: * instance.
069: */
070: public Id(String str, OpenJPAConfiguration conf,
071: ClassLoader brokerLoader) {
072: this (str, (conf == null) ? brokerLoader : conf
073: .getClassResolverInstance().getClassLoader(Id.class,
074: brokerLoader));
075: }
076:
077: /**
078: * Create an id from the result of an {@link #toString} call on another
079: * instance.
080: */
081: public Id(String str, ClassLoader loader) {
082: if (loader == null)
083: loader = (ClassLoader) AccessController
084: .doPrivileged(J2DoPrivHelper
085: .getContextClassLoaderAction());
086:
087: if (str == null)
088: _id = 0L;
089: else {
090: int dash = str.indexOf('-');
091: try {
092: type = Class.forName(str.substring(0, dash), true,
093: loader);
094: } catch (Throwable t) {
095: throw new UserException(_loc.get("string-id", str), t);
096: }
097: _id = Long.parseLong(str.substring(dash + 1));
098: }
099: }
100:
101: /**
102: * Construct from the result of a {@link #toString} call on another
103: * instance.
104: */
105: public Id(Class cls, String key) {
106: super (cls);
107:
108: if (key == null)
109: _id = 0L;
110: else {
111: // allow either stringified long or result of Id.toString
112: int dash = key.indexOf('-');
113: if (dash > 0) // don't check for -1; might be negative number
114: key = key.substring(dash + 1);
115: _id = Long.parseLong(key);
116: }
117: }
118:
119: /**
120: * Construct from key value.
121: */
122: public Id(Class cls, Long key) {
123: this (cls, (key == null) ? 0L : key.longValue());
124: }
125:
126: /**
127: * Construct from key value.
128: */
129: public Id(Class cls, long key) {
130: super (cls);
131: _id = key;
132: }
133:
134: /**
135: * Construct from key value.
136: */
137: public Id(Class cls, long key, boolean subs) {
138: super (cls, subs);
139: _id = key;
140: }
141:
142: /**
143: * Primary key.
144: */
145: public long getId() {
146: return _id;
147: }
148:
149: public Object getIdObject() {
150: return Numbers.valueOf(_id);
151: }
152:
153: protected int idHash() {
154: return (int) (_id ^ (_id >>> 32));
155: }
156:
157: protected boolean idEquals(OpenJPAId other) {
158: return _id == ((Id) other)._id;
159: }
160: }
|