001 package com.hammurapi.render;
002
003 import java.io.File;
004 import java.io.FileOutputStream;
005 import java.io.FileWriter;
006 import java.io.IOException;
007 import java.io.InputStream;
008 import java.io.Writer;
009 import java.util.HashMap;
010 import java.util.Locale;
011 import java.util.Map;
012 import java.util.zip.ZipEntry;
013 import java.util.zip.ZipInputStream;
014
015 import org.onemind.jxp.JxpContext;
016 import org.onemind.jxp.JxpProcessor;
017 import org.onemind.jxp.ResourceStreamPageSource;
018
019 import com.hammurapi.common.CompositeContext;
020 import com.hammurapi.common.Context;
021 import com.hammurapi.common.DefaultContext;
022 import com.hammurapi.common.IdentityManager;
023 import com.hammurapi.common.SimpleMutableContext;
024 import com.hammurapi.convert.ConvertingService;
025
026 /**
027 * Documentation/report generator.
028 * @author Pavel Vlasov
029 *
030 */
031 public class ReportGenerator implements RenderingConstants {
032
033
034 private static final String PATH_PREFIX = "/"+ReportGenerator.class.getName().substring(0, ReportGenerator.class.getName().lastIndexOf('.')).replace('.', '/');
035
036 private Map<String, Object> environment;
037 private Context context = new DefaultContext(null, null);
038 private Locale locale;
039
040 public Map<String, Object> getEnvironment() {
041 return environment;
042 }
043
044 public void setEnvironment(Map<String, Object> environment) {
045 this.environment = environment;
046 }
047
048 public Context getContext() {
049 return context;
050 }
051
052 public void setContext(Context context) {
053 this.context = context;
054 }
055
056 public Locale getLocale() {
057 return locale;
058 }
059
060 public void setLocale(Locale locale) {
061 this.locale = locale;
062 }
063
064 /**
065 * This method generates documentation for the root object.
066 * @param root Root object to document.
067 * @param outputFile Output file.
068 * @throws Exception
069 */
070 public void generate(Object root, File outputFile, String title, String profile, boolean http) throws RenderingException {
071
072 if (context==null) {
073 context = new DefaultContext(this.getClass().getClassLoader(), null);
074 }
075
076 // try {
077 // // Unpack resources
078 // InputStream resourcesZipStream = ReportGenerator.class.getResourceAsStream("resources.zip");
079 // if (resourcesZipStream!=null) {
080 // ZipInputStream resourceStream = new ZipInputStream(resourcesZipStream);
081 // ZipEntry entry;
082 // while ((entry = resourceStream.getNextEntry())!=null) {
083 // if ("images".equals(entry.getName()) || entry.getName().startsWith("images/")) {
084 // File rOutFile = new File(outputFile.getParentFile(), entry.getName().replace('/', File.separatorChar));
085 // if (entry.isDirectory()) {
086 // rOutFile.mkdirs();
087 // } else {
088 // FileOutputStream rOut = new FileOutputStream(rOutFile);
089 // byte[] buf = new byte[4096];
090 // int len;
091 // while ((len=resourceStream.read(buf))!=-1) {
092 // rOut.write(buf, 0, len);
093 // }
094 // rOut.close();
095 // }
096 // }
097 // }
098 // resourceStream.close();
099 // }
100 // } catch (IOException e) {
101 // throw new RenderingException("Cannot unpack resources: "+e, e);
102 // }
103
104 ResourceStreamPageSource pageSource = new ResourceStreamPageSource(PATH_PREFIX);
105 JxpContext jxpContext = new JxpContext(pageSource);
106
107 Map<String, Object> env = environment==null ? new HashMap<String, Object>() : new HashMap<String, Object>(environment);
108 env.put("title", title);
109 env.put(TO_RENDER, root);
110 // env.remove(TO_RENDER_TYPE_NAME);
111 env.put("http", http ? Boolean.TRUE : Boolean.FALSE);
112 env.put("env", env);
113 IdentityManager<?> identityManager = context.lookup(IdentityManager.class);
114 Object rootId = identityManager.getIdentity(root);
115 env.put("rootId", rootId);
116 env.put("identityManager", identityManager);
117
118 SimpleMutableContext sc = new SimpleMutableContext();
119 sc.register(JxpContext.class, jxpContext);
120
121 if (env.get(RENDER_HELPER)==null) {
122 RenderHelper renderHelper = new RenderHelper(identityManager, outputFile.getParentFile(), env, context, locale, http);
123 env.put(RENDER_HELPER, renderHelper);
124 sc.register(RenderHelper.class, renderHelper);
125 }
126
127 CompositeContext cc = new CompositeContext(sc, context);
128 env.put("context", cc);
129
130 env.put("locale", locale);
131 env.put("profile", http ? "outline" : "outline_http");
132
133 FileRenderer renderer = ConvertingService.convert(root, FileRenderer.class);
134 renderer.render(outputFile, environment, context, profile, locale);
135 }
136
137
138 /**
139 * This method creates index.html and outline.html in the target directory, extracts resources,
140 * and then uses rendering framework to generate documentation for the root object.
141 * @param root Root object to document.
142 * @param outputDir Output directory.
143 * @param http If this flag is true, outline trees use AJAX.
144 * @throws Exception
145 */
146 public void generate(Object root, File outputDir, String title, boolean http) throws RenderingException {
147
148 if (context==null) {
149 context = new DefaultContext(this.getClass().getClassLoader(), null);
150 }
151
152 if (!outputDir.exists()) {
153 outputDir.mkdirs();
154 }
155
156 try {
157 // Unpack resources
158 InputStream resourcesZipStream = ReportGenerator.class.getResourceAsStream("resources.zip");
159 if (resourcesZipStream!=null) {
160 ZipInputStream resourceStream = new ZipInputStream(resourcesZipStream);
161 ZipEntry entry;
162 while ((entry = resourceStream.getNextEntry())!=null) {
163 File rOutFile = new File(outputDir, entry.getName().replace('/', File.separatorChar));
164 if (entry.isDirectory()) {
165 rOutFile.mkdirs();
166 } else {
167 FileOutputStream rOut = new FileOutputStream(rOutFile);
168 byte[] buf = new byte[4096];
169 int len;
170 while ((len=resourceStream.read(buf))!=-1) {
171 rOut.write(buf, 0, len);
172 }
173 rOut.close();
174 }
175 }
176 resourceStream.close();
177 }
178 } catch (IOException e) {
179 throw new RenderingException("Cannot unpack resources: "+e, e);
180 }
181
182 // Write index.html
183 try {
184 ResourceStreamPageSource pageSource = new ResourceStreamPageSource(PATH_PREFIX);
185 JxpContext jxpContext = new JxpContext(pageSource);
186 JxpProcessor processor = new JxpProcessor(jxpContext);
187
188 Map<String, Object> env = environment==null ? new HashMap<String, Object>() : new HashMap<String, Object>(environment);
189 env.put("title", title);
190 env.put(TO_RENDER, root);
191 // env.remove(TO_RENDER_TYPE_NAME);
192 env.put("http", http ? Boolean.TRUE : Boolean.FALSE);
193 env.put("env", env);
194 IdentityManager<?> identityManager = context.lookup(IdentityManager.class);
195 Object rootId = identityManager.getIdentity(root);
196 env.put("rootId", rootId);
197 env.put("identityManager", identityManager);
198
199 SimpleMutableContext sc = new SimpleMutableContext();
200 sc.register(JxpContext.class, jxpContext);
201
202 if (env.get(RENDER_HELPER)==null) {
203 RenderHelper renderHelper = new RenderHelper(identityManager, outputDir, env, context, locale, http);
204 env.put(RENDER_HELPER, renderHelper);
205 sc.register(RenderHelper.class, renderHelper);
206 }
207
208 CompositeContext cc = new CompositeContext(sc, context);
209 env.put("context", cc);
210
211 env.put("locale", locale);
212 env.put("profile", http ? "outline" : "outline_http");
213
214 Writer writer = new FileWriter(new File(outputDir, "index.html"));
215 try {
216 processor.process("index.jxp", writer, env);
217 } finally {
218 writer.close();
219 }
220
221 writer = new FileWriter(new File(outputDir, "outline.html"));
222 try {
223 processor.process("outline.jxp", writer, env);
224 } finally {
225 writer.close();
226 }
227
228 } catch (Exception e) {
229 throw new RenderingException("Cannot render index.html: "+e, e);
230 }
231
232 }
233 }