001    /*
002    @license.text@
003     */
004    package biz.hammurapi.metrics.persistent;
005    
006    import java.io.File;
007    import java.io.IOException;
008    import java.sql.SQLException;
009    import java.util.ArrayList;
010    import java.util.Collection;
011    import java.util.HashMap;
012    import java.util.Iterator;
013    
014    import org.w3c.dom.Element;
015    import org.w3c.dom.Node;
016    
017    import biz.hammurapi.config.Component;
018    import biz.hammurapi.config.ConfigurationException;
019    import biz.hammurapi.config.Context;
020    import biz.hammurapi.config.DomConfigurable;
021    import biz.hammurapi.config.MapContext;
022    import biz.hammurapi.metrics.MeasurementConsumer;
023    import biz.hammurapi.metrics.MetricsException;
024    import biz.hammurapi.metrics.SlicingMeasurementCategoryFactory;
025    import biz.hammurapi.metrics.SlicingMeasurementConsumer;
026    import biz.hammurapi.sql.SQLProcessor;
027    import biz.hammurapi.xml.dom.DOMUtils;
028    
029    
030    /**
031     * @author Pavel Vlasov
032     * @revision $Revision$
033     */
034    public class HypersonicTmpPersistingSlicingMeasurementCategoryFactory extends SlicingMeasurementCategoryFactory implements Component, DomConfigurable {
035            private File outputDir;
036            private SlicingMeasurementConsumer consumer;
037            private int slices;
038            private int width;
039            private int height;
040            private Collection categories=new ArrayList();
041    
042            public MeasurementConsumer getMeasurementConsumer(String categoryName) {
043                if (categories.isEmpty() || categories.contains(categoryName)) {
044                    return consumer.getCategoryInstance(categoryName);
045                }
046                
047                Iterator it=categories.iterator();
048                while (it.hasNext()) {
049                    if (categoryName.startsWith(it.next()+".")) {
050                            return consumer.getCategoryInstance(categoryName);                                      
051                    }
052                }
053                
054                return null;
055            }
056    
057            public void start() throws ConfigurationException {
058                    if (outputDir.exists()) {
059                            if (!outputDir.isDirectory()) {
060                                    throw new ConfigurationException(outputDir.getAbsolutePath()+" in not a directory");
061                            }
062                    } else {
063                            if (!outputDir.mkdirs()) {
064                                    throw new ConfigurationException("Cannot create directory "+outputDir.getAbsolutePath());
065                            }
066                    }
067                    
068                    super.start();
069            }
070    
071            protected SlicingMeasurementConsumer createMeasurementConsumer(
072                            long tick,
073                            boolean keepMeasurements, 
074                            int maxQueue)
075                            throws ConfigurationException {
076                    try {
077                            final String rootCategory = "Root category";
078                            final HypersonicTmpSliceConsumer sliceConsumer = new HypersonicTmpSliceConsumer(
079                                                            rootCategory, 
080                                                            Long.MAX_VALUE, 
081                                                            Long.MAX_VALUE);
082                            
083                            consumer=new SlicingMeasurementConsumer(
084                                            tick, 
085                                            false, 
086                                            maxQueue, 
087                                            sliceConsumer) {
088                                                                    
089                                    public void shutdown() {
090                                            super.shutdown();
091                                            
092                                    try {
093                                                    // Generation of html's
094                                                    SQLProcessor processor=new SQLProcessor(sliceConsumer.getDataSource(), new MapContext(new HashMap()));
095                                                    PeriodFactory factory=new PeriodFactory(processor);
096                                                    SyntheticPeriod root;
097                                                    if (categories.isEmpty()) {
098                                                            root=factory.getRootPeriod(from, to, slices, false);
099                                                    } else {
100                                                            MetricLocator locator=new MetricLocator(processor);
101                                                            Collection categoryIds=new ArrayList();
102                                                            Iterator it=categories.iterator();
103                                                            while (it.hasNext()) {
104                                                                    Object id = locator.find(sliceConsumer.getRootId().intValue(), (String) it.next());
105                                                                    if (id!=null) {
106                                                                            categoryIds.add(id);
107                                                                    }
108                                                            }
109                                                            
110                                                            int[] roots=new int[categoryIds.size()];
111                                                            it=categoryIds.iterator();
112                                                            for (int i=0; it.hasNext(); i++) {
113                                                                    roots[i]=((Number) it.next()).intValue();
114                                                            }
115                                                            
116                                                            root=factory.newSyntheticPeriod(rootCategory, roots, from, to, slices, false);
117                                                    }
118                                                    
119                                                    PeriodVisualizer.generateHtmlDoc(root, outputDir, width, height);
120                                                                                                    
121                                                    sliceConsumer.getDataSource().shutdown();
122                                    } catch (SQLException e) {
123                                        throw new MetricsException(e);
124                                    }                                       
125                                    }
126                            };
127                            consumer.start();
128                            return consumer;
129                    } catch (ClassNotFoundException e) {
130                            throw new ConfigurationException(e);
131                    } catch (IOException e) {
132                            throw new ConfigurationException(e);
133                    } catch (SQLException e) {
134                            throw new ConfigurationException(e);
135                    }
136            }
137    
138            public void configure(Node configNode, Context context) throws ConfigurationException {
139                    super.configure(configNode, context);
140                    try {
141                            outputDir=new File(DOMUtils.getSingleNonBlankElementText((Element) configNode, "output-dir")); 
142                            slices=Integer.parseInt(DOMUtils.getSingleNonBlankElementText((Element) configNode, "slices"));
143                            width=Integer.parseInt(DOMUtils.getSingleNonBlankElementText((Element) configNode, "width"));
144                            height=Integer.parseInt(DOMUtils.getSingleNonBlankElementText((Element) configNode, "height"));
145                    } catch (Exception e) {
146                            throw new ConfigurationException(e);
147                    }
148            }
149    
150    }