001    /*
002    @license.text@
003     */
004    package biz.hammurapi.metrics.persistent;
005    
006    import java.sql.SQLException;
007    import java.util.Iterator;
008    import java.util.List;
009    
010    import org.w3c.dom.Element;
011    
012    import biz.hammurapi.xml.dom.DomSerializable;
013    
014    /**
015     * Measurement period for a particular metric
016     * @author Pavel Vlasov
017     * @version $Revision$
018     */
019    public class SyntheticPeriod extends AbstractPeriod implements DomSerializable {
020            private int[] ids;
021            private String id;
022            
023        /**
024         * Actual from and to can differ from the passed if shrink is true slices don't cover all the period.
025         * @param processor
026         * @param id
027         * @param from
028         * @param to
029         * @param periods
030         * @param shrink Shrink period to exclude leading and trailing times without measurements.
031         * @throws SQLException
032         */
033        SyntheticPeriod(PeriodFactory factory, String name, int[] ids, long from, long to, int slices, boolean shrink) throws SQLException {
034            this.ids=ids;
035            this.name=name;
036            MetricsEngine engine = factory.getEngine();
037            this.factory=factory;                   
038            
039            this.timeFrom=from;
040            this.timeTo=to;
041            if (shrink) {
042                    for (int i=0; i<ids.length; i++) {
043                        ActualPeriod actualPeriod = engine.getActualPeriod(ids[i], to, from);
044                        if (actualPeriod!=null && actualPeriod.getTimeFrom()!=actualPeriod.getTimeTo()) {
045                            this.timeFrom=Math.max(from, actualPeriod.getTimeFrom());
046                            this.timeTo=Math.min(to, actualPeriod.getTimeTo());
047                        }
048                    }
049            }
050            
051            createSlices(slices);
052            
053            // calculate values for slices and totals here
054            for (int i=0; i<ids.length; i++) {
055                    Iterator it=engine.getSlice(ids[i], this.timeTo, this.timeFrom).iterator();
056                    while (it.hasNext()) {
057                                    aggregate((Slice) it.next());
058                    }
059            }
060                    
061            normalizeSliceDeviations();
062            
063            StringBuffer idb=new StringBuffer("s_");
064            idb.append(from);
065            idb.append("_");
066            idb.append(to);
067            idb.append("_");
068            idb.append(slices);
069            idb.append("_");
070            idb.append(shrink);
071            for (int i=0; i<ids.length; i++) {
072                    idb.append("_");
073                    idb.append(ids[i]);
074            }
075            id=idb.toString();
076        }
077        
078            /**
079             * @throws SQLException
080             */
081            protected void loadSubCategories(List subCategories) throws SQLException {
082                    for (int i=0; i<ids.length; i++) {
083                            Period subPeriod = factory.getPeriod(ids[i], getTimeFrom(), getTimeTo(), slices.length, false); 
084                            subCategories.add(subPeriod);
085                    }
086            }
087            
088            public String getId() {
089                    return id;
090            }
091            
092            protected void setAttributes(Element holder) {
093                    super.setAttributes(holder);
094                    holder.setAttribute("id", String.valueOf(id));
095            }       
096    }