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.getPropertyEditor() != null ? Type.newSimpleType(String.class.getName()): 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