001    /**
002     * www.jcoverage.com
003     * Copyright (C)2003 jcoverage ltd.
004     *
005     * This file is part of jcoverage.
006     *
007     * jcoverage is free software; you can redistribute it and/or modify
008     * it under the terms of the GNU General Public License as published
009     * by the Free Software Foundation; either version 2 of the License,
010     * or (at your option) any later version.
011     *
012     * jcoverage is distributed in the hope that it will be useful, but
013     * WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     * General Public License for more details.
016     *
017     * You should have received a copy of the GNU General Public License
018     * along with jcoverage; if not, write to the Free Software
019     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
020     * USA
021     *
022     */
023    package com.jcoverage.reporting;
024    
025    import java.util.HashMap;
026    import java.util.Map;
027    import org.apache.log4j.Logger;
028    
029    /**
030     * This class provides a skeletal implementation of a {@link
031     * Line}.  Subclasses should override the {@link
032     * #instantiateDetailPage} method if the line provides a
033     * deeper detail page.
034     */
035    public class AbstractLine implements Line {
036      
037      static Logger logger=Logger.getLogger(AbstractLine.class);
038      
039      Report report;
040      Page owner,detailPage;
041      LineCategory category;
042      Map fieldsByColumn=new HashMap();
043      int state=Report.READY;
044    
045      public Page openDetailPage() {
046        if (detailPage!=null) {
047          throw new IllegalStateException();
048        }
049        detailPage=instantiateDetailPage();
050        if (detailPage!=null) {
051          detailPage.setMasterLine(this);
052          detailPage.setReport(report);
053        }
054        return detailPage;
055      }
056      
057      /**
058       * Set the page that own's this line, in other words, the master page.
059       */
060      public void setOwner(Page owner) {
061        this.owner=owner;
062      }
063    
064      public Page getOwner() {
065        return owner;
066      }
067    
068      public void setReport(Report report) {
069        this.report=report;
070      }
071    
072      public void setCategory(LineCategory category) {
073        this.category=category;
074      }
075    
076      public Page getDetailPage() {
077        return detailPage;
078      }
079    
080      /**
081       * Set a piece of information against this line.
082       */
083      public void setField(Column column,Object value) {
084        assertValidColumnForCategory(column);
085        if (column.getType() instanceof Object && column.isAcceptableValue(value)) {
086          fieldsByColumn.put(column,value);
087        } else {
088          throw new IllegalArgumentException("Column "+column+" does not accept values of type "+value.getClass());
089        }
090      }
091    
092      public void setField(Column column,int value) {
093        setField(column,new Integer(value));
094      }
095    
096      public void setField(Column column,double value) {
097        setField(column,new Double(value));
098      }
099    
100      public void setField(Column column,boolean value) {
101        setField(column,new Boolean(value));
102      }
103    
104      /**
105       * Subclasses should override this method if the line has
106       * information in a detail page.
107       */
108      protected Page instantiateDetailPage() {
109        return null;
110      }
111    
112      /**
113       * Get the field value for a given column.
114       * <ul>
115       * <li>ints are returned as Integer instances.
116       * <li>doubles are returned as Double instances.
117       * <li>booleans are returned as Boolean instances.
118       * </ul>
119       * @param column the given column.
120       * @return null if no value has been set for the given column.
121       * @throws IllegalArgumentException if the column is not known to
122       * this line's category.
123       */
124      public Object getField(Column column) throws IllegalArgumentException {
125        assertValidColumnForCategory(column);
126        return fieldsByColumn.get(column);
127      }
128    
129      public void close() throws ReportingException {
130        state=Report.CLOSED;
131        if (getDetailPage()!=null) {
132          getDetailPage().close();
133        }
134      }
135    
136      public boolean isClosed() {
137        return state==Report.CLOSED;
138      }
139    
140      protected void assertValidColumnForCategory(Column column) throws IllegalArgumentException {
141        if (category==null) {
142          return;
143        }
144        if (!category.getColumns().contains(column)) {
145          throw new IllegalArgumentException("Column "+column+" cannot be used here since it is unknown to this line's category, which is "+category+"("+category.getClass().getName()+")");
146        }
147      }
148    
149    }