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.persistence;
020:
021: import serp.util.Strings;
022:
023: import java.util.List;
024: import java.util.ArrayList;
025: import java.util.Iterator;
026: import java.util.EnumSet;
027: import java.lang.annotation.Annotation;
028:
029: import org.apache.commons.lang.StringUtils;
030:
031: /**
032: * Helper class to stringify annotation declarations.
033: *
034: * @author Gokhan Ergul
035: * @since 1.0.0
036: * @nojavadoc
037: */
038: public class AnnotationBuilder {
039:
040: private Class<? extends Annotation> type;
041: private List<AnnotationEntry> components = new ArrayList<AnnotationEntry>();
042:
043: protected AnnotationBuilder(Class<? extends Annotation> type) {
044: this .type = type;
045: }
046:
047: public Class<? extends Annotation> getType() {
048: return this .type;
049: }
050:
051: public AnnotationBuilder add(String key, String val) {
052: return doAdd(key, val);
053: }
054:
055: public AnnotationBuilder add(String key, boolean val) {
056: return doAdd(key, val);
057: }
058:
059: public AnnotationBuilder add(String key, int val) {
060: return doAdd(key, val);
061: }
062:
063: public AnnotationBuilder add(String key, Class val) {
064: return doAdd(key, val);
065: }
066:
067: public AnnotationBuilder add(String key, EnumSet val) {
068: return doAdd(key, val);
069: }
070:
071: public AnnotationBuilder add(String key, Enum val) {
072: return doAdd(key, val);
073: }
074:
075: @SuppressWarnings("unchecked")
076: public AnnotationBuilder add(String key, AnnotationBuilder val) {
077: if (null == val)
078: return this ;
079: AnnotationEntry ae = find(key);
080: if (null == ae) {
081: doAdd(key, val);
082: } else {
083: List<AnnotationBuilder> list;
084: if (ae.value instanceof List) {
085: list = (List<AnnotationBuilder>) ae.value;
086: } else if (ae.value instanceof AnnotationBuilder) {
087: list = new ArrayList<AnnotationBuilder>();
088: list.add((AnnotationBuilder) ae.value);
089: ae.value = list;
090: } else {
091: throw new IllegalArgumentException("Unexpected type: "
092: + ae.value);
093: }
094: list.add(val);
095: }
096: return this ;
097: }
098:
099: public boolean hasComponents() {
100: return components.size() > 0;
101: }
102:
103: private AnnotationBuilder doAdd(String key, Object val) {
104: if (null != val)
105: components.add(new AnnotationEntry(key, val));
106: return this ;
107: }
108:
109: private AnnotationEntry find(String key) {
110: for (AnnotationEntry ae : components) {
111: // null key references considered equal
112: if (StringUtils.equals(ae.key, key))
113: return ae;
114: }
115: return null;
116: }
117:
118: static String enumToString(Enum e) {
119: StringBuilder sb = new StringBuilder();
120: sb.append(Strings.getClassName(e.getClass())).append(".")
121: .append(e);
122: return sb.toString();
123: }
124:
125: static String enumSetToString(EnumSet set) {
126: StringBuilder sb = new StringBuilder();
127: for (Iterator i = set.iterator(); i.hasNext();) {
128: Object e = i.next();
129: sb.append(Strings.getClassName(e.getClass())).append(".")
130: .append(e);
131: if (i.hasNext())
132: sb.append(", ");
133: }
134: return sb.toString();
135: }
136:
137: protected void toString(StringBuilder sb) {
138: sb.append("@").append(Strings.getClassName(type));
139: if (components.size() == 0)
140: return;
141: sb.append("(");
142: for (Iterator<AnnotationEntry> i = components.iterator(); i
143: .hasNext();) {
144: AnnotationEntry e = i.next();
145: e.toString(sb);
146: if (i.hasNext())
147: sb.append(", ");
148: }
149: sb.append(")");
150: }
151:
152: public String toString() {
153: StringBuilder sb = new StringBuilder();
154: toString(sb);
155: return sb.toString();
156: }
157:
158: class AnnotationEntry {
159:
160: String key;
161: Object value;
162:
163: AnnotationEntry(String key, Object value) {
164: this .key = key;
165: this .value = value;
166: }
167:
168: @SuppressWarnings("unchecked")
169: void toString(StringBuilder sb) {
170: if (null != key)
171: sb.append(key).append("=");
172:
173: List.class.getTypeParameters();
174: if (value instanceof List) {
175: sb.append("{");
176: List<AnnotationBuilder> l = (List<AnnotationBuilder>) value;
177: for (Iterator<AnnotationBuilder> i = l.iterator(); i
178: .hasNext();) {
179: AnnotationBuilder ab = i.next();
180: sb.append(ab.toString());
181: if (i.hasNext())
182: sb.append(", ");
183: }
184: sb.append("}");
185: } else if (value instanceof Class) {
186: String cls = ((Class) value).getName()
187: .replace('$', '.');
188: sb.append(cls).append(".class");
189: } else if (value instanceof String) {
190: sb.append('"').append(value).append('"');
191: } else if (value instanceof Enum) {
192: sb.append(AnnotationBuilder.enumToString((Enum) value));
193: } else if (value instanceof EnumSet) {
194: sb.append(AnnotationBuilder
195: .enumSetToString((EnumSet) value));
196: } else {
197: sb.append(value);
198: }
199: }
200:
201: }
202: }
|