001: /*
002: Copyright (c) 2004-2007, Dennis M. Sosnoski
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JiBX nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jibx.binding.generator;
030:
031: import org.jibx.binding.classes.ClassItem;
032: import org.jibx.binding.model.ClassItemWrapper;
033: import org.jibx.binding.model.IClass;
034: import org.jibx.binding.model.IClassLocator;
035:
036: import com.thoughtworks.qdox.model.DocletTag;
037: import com.thoughtworks.qdox.model.JavaClass;
038: import com.thoughtworks.qdox.model.JavaField;
039: import com.thoughtworks.qdox.model.JavaMethod;
040: import com.thoughtworks.qdox.model.JavaParameter;
041: import com.thoughtworks.qdox.model.Member;
042:
043: /**
044: * Wrapper for class field or method item with added source information. This
045: * wraps the basic class handling implementation with added support for
046: * retrieving information from source files.
047: *
048: * @author Dennis M. Sosnoski
049: */
050: public class ClassItemSourceWrapper extends ClassItemWrapper {
051: private boolean m_checkedSource;
052: private Member m_itemSource;
053:
054: /**
055: * Constructor
056: * @param clas
057: * @param item
058: */
059: /*package*/ClassItemSourceWrapper(IClass clas, ClassItem item) {
060: super (clas, item);
061: }
062:
063: /**
064: * Check for source method signature match.
065: *
066: * @param method
067: * @return <code>true</code> if match to this method, <code>false</code> if
068: * not
069: */
070: private boolean matchSignature(JavaMethod method) {
071: boolean match = true;
072: JavaParameter[] parms = method.getParameters();
073: if (parms.length == getArgumentCount()) {
074: for (int j = 0; j < parms.length; j++) {
075: String type = parms[j].getType().getValue();
076: String comp = getArgumentType(j);
077: if (!comp.equals(type)) {
078: if (type.indexOf('.') >= 0
079: || !comp.endsWith('.' + type)) {
080: match = false;
081: break;
082: }
083: }
084: }
085: }
086: return match;
087: }
088:
089: /**
090: * Internal method to get the source code information for this item.
091: *
092: * @return source information
093: */
094: private Member getItemSource() {
095: if (!m_checkedSource) {
096: m_checkedSource = true;
097: IClass clas = getContainingClass();
098: IClassLocator loc = clas.getLocator();
099: if (loc instanceof IClassSourceLocator) {
100: IClassSourceLocator sloc = (IClassSourceLocator) loc;
101: JavaClass jc = sloc.getSourceInfo(clas.getName());
102: if (jc != null) {
103: if (isMethod()) {
104: String mname = getName();
105: JavaMethod[] methods = jc.getMethods();
106: for (int i = 0; i < methods.length; i++) {
107: JavaMethod method = methods[i];
108: if (mname.equals(method.getName())) {
109: if (matchSignature(method)) {
110: m_itemSource = method;
111: break;
112: }
113: }
114: }
115: } else {
116: m_itemSource = jc.getFieldByName(getName());
117: }
118: }
119: }
120: }
121: return m_itemSource;
122: }
123:
124: /**
125: * Return JavaDoc text only if non-empty.
126: *
127: * @param text raw JavaDoc text
128: * @return trimmed text if non-empty, otherwise <code>null</code>
129: */
130: private static String docText(String text) {
131: if (text != null) {
132: text = text.trim();
133: if (text.length() > 0) {
134: return text;
135: }
136: }
137: return null;
138: }
139:
140: /* (non-Javadoc)
141: * @see org.jibx.binding.model.IClassItem#getJavaDoc()
142: */
143: public String getJavaDoc() {
144: Member src = getItemSource();
145: if (src == null) {
146: return null;
147: } else if (isMethod()) {
148: return docText(((JavaMethod) src).getComment());
149: } else {
150: return docText(((JavaField) src).getComment());
151: }
152: }
153:
154: /* (non-Javadoc)
155: * @see org.jibx.binding.model.IClassItem#getReturnJavaDoc()
156: */
157: public String getReturnJavaDoc() {
158: if (isMethod()) {
159: JavaMethod jm = (JavaMethod) getItemSource();
160: if (jm != null) {
161: DocletTag tag = jm.getTagByName("return");
162: if (tag != null) {
163: return docText(tag.getValue());
164: }
165: }
166: return null;
167: } else {
168: throw new IllegalStateException(
169: "Internal error: not a method");
170: }
171: }
172:
173: /* (non-Javadoc)
174: * @see org.jibx.binding.model.IClassItem#getParameterJavaDoc(int)
175: */
176: public String getParameterJavaDoc(int index) {
177: if (isMethod()) {
178: JavaMethod jm = (JavaMethod) getItemSource();
179: if (jm != null) {
180: String name = jm.getParameters()[index].getName();
181: DocletTag[] tags = jm.getTagsByName("param");
182: for (int i = 0; i < tags.length; i++) {
183: DocletTag tag = tags[i];
184: String[] parms = tag.getParameters();
185: if (parms != null && parms.length > 0
186: && name.equals(parms[0])) {
187: String text = tag.getValue().trim();
188: if (text.startsWith(name)) {
189: text = text.substring(name.length()).trim();
190: }
191: return docText(text);
192: }
193: }
194: }
195: return null;
196: } else {
197: throw new IllegalStateException(
198: "Internal error: not a method");
199: }
200: }
201:
202: /* (non-Javadoc)
203: * @see org.jibx.binding.model.IClassItem#getParameterName(int)
204: */
205: public String getParameterName(int index) {
206: String name = super .getParameterName(index);
207: if (name == null) {
208: JavaMethod jm = (JavaMethod) getItemSource();
209: if (jm != null) {
210: name = jm.getParameters()[index].getName();
211: }
212: }
213: return name;
214: }
215:
216: /* (non-Javadoc)
217: * @see org.jibx.binding.model.IClassItem#getExceptionJavaDoc(int)
218: */
219: public String getExceptionJavaDoc(int index) {
220: if (isMethod()) {
221: JavaMethod jm = (JavaMethod) getItemSource();
222: if (jm != null) {
223: String name = getExceptions()[index];
224: DocletTag[] tags = jm.getTagsByName("throws");
225: for (int i = 0; i < tags.length; i++) {
226: DocletTag tag = tags[i];
227: String[] parms = tag.getParameters();
228: if (parms != null && parms.length > 0
229: && name.equals(parms[0])) {
230: return docText(tag.getValue());
231: }
232: }
233: }
234: return null;
235: } else {
236: throw new IllegalStateException(
237: "Internal error: not a method");
238: }
239: }
240: }
|