001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.pageflow.internal;
020:
021: import org.apache.beehive.netui.pageflow.PageFlowConstants;
022: import org.apache.beehive.netui.pageflow.internal.annotationreader.AnnotationAttribute;
023: import org.apache.beehive.netui.pageflow.internal.annotationreader.ProcessedAnnotation;
024: import org.apache.beehive.netui.pageflow.internal.annotationreader.ProcessedAnnotations;
025: import org.apache.beehive.netui.pageflow.internal.annotationreader.ProcessedAnnotationParser;
026: import org.apache.beehive.netui.util.internal.concurrent.InternalConcurrentHashMap;
027: import org.apache.beehive.netui.util.logging.Logger;
028:
029: import javax.servlet.ServletContext;
030: import java.io.InputStream;
031: import java.io.IOException;
032: import java.io.Serializable;
033: import java.lang.reflect.Member;
034: import java.util.Iterator;
035: import java.util.Map;
036:
037: /**
038: * Utility for reading XML files that describe annotations in classes. These files are generated during
039: * Page Flow build.
040: */
041: public class AnnotationReader implements Serializable {
042: private static final Logger _log = Logger
043: .getInstance(AnnotationReader.class);
044: private static final String CACHE_ATTR = InternalConstants.ATTR_PREFIX
045: + "annCache";
046:
047: private ProcessedAnnotations _annotations;
048:
049: public static AnnotationReader getAnnotationReader(Class type,
050: ServletContext servletContext) {
051: InternalConcurrentHashMap cache = (InternalConcurrentHashMap) servletContext
052: .getAttribute(CACHE_ATTR);
053:
054: if (cache == null) {
055: cache = new InternalConcurrentHashMap();
056: servletContext.setAttribute(CACHE_ATTR, cache);
057: }
058:
059: AnnotationReader reader = (AnnotationReader) cache.get(type);
060:
061: if (reader == null) {
062: reader = new AnnotationReader(type, servletContext);
063: cache.put(type, reader);
064: }
065:
066: return reader;
067: }
068:
069: private AnnotationReader(Class type, ServletContext servletContext) {
070: String annotationsXml = PageFlowConstants.PAGEFLOW_MODULE_CONFIG_GEN_DIR
071: + "/annotations-"
072: + type.getName().replace('.', '-')
073: + ".xml";
074: InputStream in = servletContext
075: .getResourceAsStream(annotationsXml);
076: if (in == null) {
077: assert annotationsXml.startsWith("/") : annotationsXml;
078: annotationsXml = annotationsXml.substring(1);
079: in = Thread.currentThread().getContextClassLoader()
080: .getResourceAsStream(annotationsXml);
081: }
082:
083: if (in != null) {
084: _annotations = ProcessedAnnotationParser.parse(
085: annotationsXml, in);
086: try {
087: in.close();
088: } catch (IOException e) {
089: _log.error("Could not close input stream for "
090: + annotationsXml, e);
091: }
092: }
093: }
094:
095: public ProcessedAnnotation getAnnotation(String declarationName,
096: String annotationTypeName) {
097: if (_annotations == null)
098: return null;
099:
100: Map elements = _annotations.getAnnotatedElements();
101:
102: for (Iterator i = elements.keySet().iterator(); i.hasNext();) {
103: String name = (String) i.next();
104: if (name.equals(declarationName)) {
105: // For now, we can be sure that there's only one element in this array.
106: ProcessedAnnotation[] annotations = (ProcessedAnnotation[]) elements
107: .get(name);
108: assert annotations.length == 1 : annotations.length;
109: ProcessedAnnotation pa = annotations[0];
110: return pa.getAnnotationName()
111: .equals(annotationTypeName) ? pa : null;
112: }
113: }
114:
115: return null;
116: }
117:
118: public ProcessedAnnotation getJpfAnnotation(Member member,
119: String annotationTypeName) {
120: return getAnnotation(member.getName(),
121: InternalConstants.ANNOTATION_QUALIFIER
122: + annotationTypeName);
123: }
124:
125: public ProcessedAnnotation getJpfAnnotation(Class type,
126: String annotationTypeName) {
127: return getAnnotation(type.getName(),
128: InternalConstants.ANNOTATION_QUALIFIER
129: + annotationTypeName);
130: }
131:
132: public static String getStringAttribute(ProcessedAnnotation ann,
133: String attrName) {
134: AnnotationAttribute[] attrs = ann.getAnnotationAttributes();
135:
136: for (int i = 0; i < attrs.length; i++) {
137: AnnotationAttribute attr = attrs[i];
138:
139: if (attr.getAttributeName().equals(attrName)) {
140: String value = attr.getStringValue();
141: assert value != null : "attribute " + attrName
142: + " did not have a String value";
143: return value;
144: }
145: }
146:
147: return null;
148: }
149:
150: public static ProcessedAnnotation[] getAnnotationArrayAttribute(
151: ProcessedAnnotation ann, String attrName) {
152: AnnotationAttribute[] attrs = ann.getAnnotationAttributes();
153:
154: for (int i = 0; i < attrs.length; i++) {
155: AnnotationAttribute attr = attrs[i];
156:
157: if (attr.getAttributeName().equals(attrName)) {
158: ProcessedAnnotation[] array = attr
159: .getAnnotationValues();
160: assert array != null : "attribute " + attrName
161: + " did not have an array of annotations.";
162: return array;
163: }
164: }
165:
166: return null;
167: }
168: }
|