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    }