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 package org.apache.xbean.spring.generator;
018
019 import java.io.File;
020 import java.io.FileWriter;
021 import java.io.IOException;
022 import java.io.PrintWriter;
023 import java.util.ArrayList;
024 import java.util.Collection;
025 import java.util.HashMap;
026 import java.util.Iterator;
027 import java.util.Map;
028 import java.util.Map.Entry;
029
030 /**
031 * @author Hiram Chirino
032 * @version $Id$
033 * @since 1.0
034 */
035 public class WikiDocumentationGenerator implements GeneratorPlugin {
036 private final File destFile;
037 private LogFacade log;
038
039 public WikiDocumentationGenerator(File destFile) {
040 this.destFile = destFile;
041 }
042
043 public void generate(NamespaceMapping namespaceMapping) throws IOException {
044 String namespace = namespaceMapping.getNamespace();
045 File file = new File(destFile.getParentFile(), destFile.getName() + ".wiki");
046 log.log("Generating WIKI documentation file: " + file + " for namespace: " + namespace);
047 PrintWriter out = new PrintWriter(new FileWriter(file));
048 try {
049 generateDocumentation(out, namespaceMapping);
050 } finally {
051 out.close();
052 }
053 }
054
055 private void generateDocumentation(PrintWriter out, NamespaceMapping namespaceMapping) {
056 HashMap refercencedTypes = new HashMap();
057
058 // Build of map of types that are referenced by element types.
059 for (Iterator iter = namespaceMapping.getElements().iterator(); iter.hasNext();) {
060 ElementMapping element = (ElementMapping) iter.next();
061 for (Iterator iterator = element.getAttributes().iterator(); iterator.hasNext();) {
062 AttributeMapping attribute = (AttributeMapping) iterator.next();
063 Type type = getNestedType( attribute.getType() );
064
065 if( namespaceMapping.isSimpleType( type) )
066 continue;
067
068 if( !refercencedTypes.containsKey(type.getName()) )
069 refercencedTypes.put(type.getName(), new ArrayList());
070 }
071 }
072
073 // Add all the elements that implement those types.
074 for (Iterator iter = refercencedTypes.entrySet().iterator(); iter.hasNext();) {
075
076 Map.Entry entry = (Map.Entry) iter.next();
077 String type = (String) entry.getKey();
078 ArrayList implementations = (ArrayList) entry.getValue();
079
080 for (Iterator iterator = namespaceMapping.getElements().iterator(); iterator.hasNext();) {
081 ElementMapping element = (ElementMapping) iterator.next();
082
083 // Check to see if the class is matches
084 boolean matched=false;
085 if (type.equals(element.getClassName())) {
086 implementations.add(element);
087 matched=true;
088 }
089
090 // Perhaps a super class matches.
091 if(!matched) {
092 for (Iterator j = element.getSuperClasses().iterator(); j.hasNext();) {
093 String t = (String) j.next();
094 if( type.equals(t) ) {
095 implementations.add(element);
096 matched=true;
097 break;
098 }
099 }
100 }
101
102 // Or it might be an interface.
103 if(!matched) {
104 for (Iterator j = element.getInterfaces().iterator(); j.hasNext();) {
105 String t = (String) j.next();
106 if( type.equals(t) ) {
107 implementations.add(element);
108 matched=true;
109 break;
110 }
111 }
112 }
113 }
114 }
115
116 // Remove any entries that did not have associated elements
117 for (Iterator iter = refercencedTypes.values().iterator(); iter.hasNext();) {
118 ArrayList implementations = (ArrayList) iter.next();
119 if( implementations.isEmpty() )
120 iter.remove();
121 }
122
123 generateElementsByType(out, namespaceMapping, refercencedTypes);
124 generateElementsDetail(out, namespaceMapping, refercencedTypes);
125 generateElementsIndex(out, namespaceMapping, refercencedTypes);
126 }
127
128 private Type getNestedType(Type type) {
129 if( type.isCollection() ) {
130 return getNestedType(type.getNestedType());
131 } else {
132 return type;
133 }
134 }
135
136 private void generateElementsByType(PrintWriter out, NamespaceMapping namespaceMapping, HashMap refercencedTypes) {
137 out.println("h3. Elements By Type");
138 for (Iterator iter = refercencedTypes.entrySet().iterator(); iter.hasNext();) {
139 Entry entry = (Entry) iter.next();
140 String className = (String) entry.getKey();
141 Collection elements = (Collection) entry.getValue();
142
143 out.println("{anchor:"+className+"-types}");
144 out.println("h4. The _["+className+"|#"+className+"-types]_ Type Implementations");
145
146 for (Iterator iterator = elements.iterator(); iterator.hasNext();) {
147 ElementMapping element = (ElementMapping) iterator.next();
148 out.println(" | _[<"+element.getElementName() +">|#"+element.getElementName() +"-element]_ | {html}"+element.getDescription()+"{html} |");
149 }
150 out.println();
151 }
152 out.println();
153 }
154
155 private void generateElementsIndex(PrintWriter out, NamespaceMapping namespaceMapping, HashMap refercencedTypes) {
156
157 out.println("h3. Element Index");
158 for (Iterator iter = namespaceMapping.getElements().iterator(); iter.hasNext();) {
159 ElementMapping element = (ElementMapping) iter.next();
160 out.println(" | _[<"+element.getElementName() +">|#"+element.getElementName() +"-element]_ | {html}"+element.getDescription()+"{html} |");
161 }
162 out.println();
163 }
164
165 private void generateElementsDetail(PrintWriter out, NamespaceMapping namespaceMapping, HashMap refercencedTypes) {
166 for (Iterator iter = namespaceMapping.getElements().iterator(); iter.hasNext();) {
167 ElementMapping element = (ElementMapping) iter.next();
168 generateElementDetail(out, namespaceMapping, element, refercencedTypes);
169 }
170 }
171
172 private void generateElementDetail(PrintWriter out, NamespaceMapping namespaceMapping, ElementMapping element, HashMap refercencedTypes) {
173
174 out.println("{anchor:" + element.getElementName() + "-element}");
175 out.println("h3. The _[<" + element.getElementName() + ">|#" + element.getElementName() + "-element]_ Element");
176
177 out.println(" {html}"+element.getDescription()+"{html}");
178
179 if( element.getAttributes().size() > 0 ) {
180 out.println("h4. Properties");
181 out.println(" || Property Name || Type || Description ||");
182
183 for ( Iterator iterator = element.getAttributes().iterator(); iterator.hasNext(); ) {
184 AttributeMapping attribute = (AttributeMapping) iterator.next();
185 Type type = attribute.getType();
186 out.println(" | " + attribute.getAttributeName() + " | "+getTypeLink(type, refercencedTypes)+" | {html}"+attribute.getDescription()+"{html} |");
187 }
188 }
189 out.println();
190 }
191
192 private String getTypeLink(Type type, HashMap refercencedTypes) {
193 if (type.isCollection()) {
194 return "(" + getTypeLink(type.getNestedType(), refercencedTypes) + ")\\*";
195 } else {
196 if( refercencedTypes.containsKey(type.getName()) ) {
197 return "_["+type.getName()+"|#"+type.getName()+"-types]_";
198 } else {
199 return "_"+type.getName()+"_";
200 }
201 }
202 }
203
204 public LogFacade getLog() {
205 return log;
206 }
207
208 public void setLog(LogFacade log) {
209 this.log = log;
210 }
211 }
212