001: /*
002: The contents of this file are subject to the Common Public Attribution License
003: Version 1.0 (the "License"); you may not use this file except in compliance with
004: the License. You may obtain a copy of the License at
005: http://www.projity.com/license . The License is based on the Mozilla Public
006: License Version 1.1 but Sections 14 and 15 have been added to cover use of
007: software over a computer network and provide for limited attribution for the
008: Original Developer. In addition, Exhibit A has been modified to be consistent
009: with Exhibit B.
010:
011: Software distributed under the License is distributed on an "AS IS" basis,
012: WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
013: specific language governing rights and limitations under the License. The
014: Original Code is OpenProj. The Original Developer is the Initial Developer and
015: is Projity, Inc. All portions of the code written by Projity are Copyright (c)
016: 2006, 2007. All Rights Reserved. Contributors Projity, Inc.
017:
018: Alternatively, the contents of this file may be used under the terms of the
019: Projity End-User License Agreeement (the Projity License), in which case the
020: provisions of the Projity License are applicable instead of those above. If you
021: wish to allow use of your version of this file only under the terms of the
022: Projity License and not to allow others to use your version of this file under
023: the CPAL, indicate your decision by deleting the provisions above and replace
024: them with the notice and other provisions required by the Projity License. If
025: you do not delete the provisions above, a recipient may use your version of this
026: file under either the CPAL or the Projity License.
027:
028: [NOTE: The text of this license may differ slightly from the text of the notices
029: in Exhibits A and B of the license at http://www.projity.com/license. You should
030: use the latest text at http://www.projity.com/license for your modifications.
031: You may not remove this license text from the source files.]
032:
033: Attribution Information: Attribution Copyright Notice: Copyright © 2006, 2007
034: Projity, Inc. Attribution Phrase (not exceeding 10 words): Powered by OpenProj,
035: an open source solution from Projity. Attribution URL: http://www.projity.com
036: Graphic Image as provided in the Covered Code as file: openproj_logo.png with
037: alternatives listed on http://www.projity.com/logo
038:
039: Display of Attribution Information is required in Larger Works which are defined
040: in the CPAL as a work which combines Covered Code or portions thereof with code
041: not governed by the terms of the CPAL. However, in addition to the other notice
042: obligations, all copies of the Covered Code in Executable and Source Code form
043: distributed must, as a form of attribution of the original author, include on
044: each user interface screen the "OpenProj" logo visible to all users. The
045: OpenProj logo should be located horizontally aligned with the menu bar and left
046: justified on the top left of the screen adjacent to the File menu. The logo
047: must be at least 100 x 25 pixels. When users click on the "OpenProj" logo it
048: must direct them back to http://www.projity.com.
049: */
050: package com.projity.reports.adapter;
051:
052: import java.util.Collection;
053: import java.util.HashMap;
054: import java.util.Iterator;
055:
056: import net.sf.jasperreports.engine.JRBand;
057: import net.sf.jasperreports.engine.JRDataSource;
058: import net.sf.jasperreports.engine.JRDataSourceProvider;
059: import net.sf.jasperreports.engine.JRElement;
060: import net.sf.jasperreports.engine.JRException;
061: import net.sf.jasperreports.engine.JRField;
062: import net.sf.jasperreports.engine.JRTextElement;
063: import net.sf.jasperreports.engine.JasperReport;
064: import net.sf.jasperreports.engine.design.JRDesignBand;
065: import net.sf.jasperreports.engine.design.JRDesignExpression;
066: import net.sf.jasperreports.engine.design.JRDesignField;
067: import net.sf.jasperreports.engine.design.JRDesignReportFont;
068: import net.sf.jasperreports.engine.design.JRDesignStaticText;
069: import net.sf.jasperreports.engine.design.JRDesignTextField;
070: import net.sf.jasperreports.engine.design.JasperDesign;
071:
072: import org.apache.commons.collections.Predicate;
073:
074: import com.projity.configuration.Configuration;
075: import com.projity.datatype.Duration;
076: import com.projity.datatype.Money;
077: import com.projity.datatype.Rate;
078: import com.projity.field.Field;
079: import com.projity.grouping.core.model.WalkersNodeModel;
080: import com.projity.grouping.core.transform.filtering.PredicatedNodeFilterIterator;
081: import com.projity.pm.assignment.Assignment;
082: import com.projity.pm.resource.ResourceImpl;
083: import com.projity.pm.task.Project;
084: import com.projity.pm.task.Task;
085: import com.projity.strings.Messages;
086: import com.projity.timescale.TimeInterval;
087: import com.projity.timescale.TimeIterator;
088:
089: /**
090: *
091: */
092: public class DataSourceProvider implements JRDataSourceProvider {
093: public static final int PROJECT = 0; // just the current project's fields
094: public static final int PROJECTS_TREE = 1;
095: public static final int PROJECTS_FLAT = 2;
096: public static final int TASKS_TREE = 3;
097: public static final int TASKS_FLAT = 4;
098: public static final int RESOURCES_TREE = 5;
099: public static final int RESOURCES_FLAT = 6;
100: public static final int ASSIGNMENTS = 7;
101: public static final int PREDECESSORS = 8;
102: public static final int SUCCESSORS = 9;
103: public static final int TASKS_ASSIGNMENTS_TREE = 10;
104: public static final int RESOURCES_ASSIGNMENTS_TREE = 11;
105: public static final int TASKS_ASSIGNMENTS_FLAT = 12;
106: public static final int RESOURCES_ASSIGNMENTS_FLAT = 13;
107: public static final int ASSIGNMENTS_PROJECT_BASED = 14;
108: public static final int ASSIGNMENTS_RESOURCE_BASED = 15;
109:
110: public static final String REPORT_VIEW = Messages
111: .getString("View.Report");
112:
113: public static final String PROJECT_REPORT_VIEW = Messages
114: .getString("View.ProjectReport");
115: public static final String TASK_REPORT_VIEW = Messages
116: .getString("View.TaskReport");
117: public static final String RESOURCE_REPORT_VIEW = Messages
118: .getString("View.ResourceReport");
119:
120: public static final String COLLECTION_TYPE_PROPERTY = "collectionType";
121: public static final String OUTLINE_PROPERTY = "outline";
122: public static final String TIME_BASED = "timeBased";
123: private static DataSourceProvider instance = null;
124: private JRField[] reportFields = null;
125:
126: public static DataSourceProvider getInstance() {
127: if (instance == null)
128: instance = new DataSourceProvider();
129: return instance;
130: }
131:
132: HashMap map = new HashMap();
133:
134: /* (non-Javadoc)
135: * @see net.sf.jasperreports.engine.JRDataSourceProvider#supportsGetFieldsOperation()
136: */
137: public boolean supportsGetFieldsOperation() {
138: return true;
139: }
140:
141: private void initFields() {
142: Collection allFields = Configuration.getAllFields();
143: reportFields = new JRField[allFields.size()];
144: int index = 0;
145: Iterator i = allFields.iterator();
146: JRDesignField newOne;
147: Field field;
148: JRField f;
149: while (i.hasNext()) {
150: field = (Field) i.next();
151: newOne = new JRDesignField();
152: newOne.setName(field.getId());
153: newOne.setDescription(field.getName());
154: newOne.setValueClass(field.getClazz());
155: newOne.setValueClassName(field.getDisplayType().getName()); //TODO what should this be?
156: map.put(newOne, field);
157: }
158: }
159:
160: public JRField[] getFields(JasperReport arg0) throws JRException,
161: UnsupportedOperationException {
162: if (reportFields == null)
163: initFields();
164: return reportFields;
165: }
166:
167: /**
168: * JasperAssistant version
169: */
170: public JRDataSource create(JasperReport arg0) throws JRException {
171: DataSource dataSource = new DataSource();
172: return dataSource;
173: }
174:
175: /**
176: * get the view corresponding to a report. This is used primarily to set filter and sort combos
177: * @param report
178: * @return
179: */
180: public static String getViewName(JasperReport report) {
181: String collectionType = report
182: .getProperty(COLLECTION_TYPE_PROPERTY);
183: int type = Integer.parseInt(collectionType);
184: switch (type) {
185: case PROJECT:
186: return REPORT_VIEW;
187: case PROJECTS_TREE:
188: case PROJECTS_FLAT:
189: return PROJECT_REPORT_VIEW;
190: case TASKS_TREE:
191: case TASKS_FLAT:
192: case TASKS_ASSIGNMENTS_TREE:
193: case TASKS_ASSIGNMENTS_FLAT:
194: case ASSIGNMENTS_PROJECT_BASED:
195: return TASK_REPORT_VIEW;
196: case RESOURCES_TREE:
197: case RESOURCES_FLAT:
198: case RESOURCES_ASSIGNMENTS_TREE:
199: case RESOURCES_ASSIGNMENTS_FLAT:
200: case ASSIGNMENTS_RESOURCE_BASED:
201: return RESOURCE_REPORT_VIEW;
202: default:
203: return null;
204: }
205:
206: }
207:
208: public static DataSource createDataSource(JasperReport report,
209: Project project,
210: PredicatedNodeFilterIterator cacheIterator,
211: WalkersNodeModel walkersNodeModel) throws JRException {
212: DataSource dataSource = new DataSource();
213: boolean timeBased = report.getProperty(TIME_BASED) != null;
214: String collectionType = report
215: .getProperty(COLLECTION_TYPE_PROPERTY);
216: if (collectionType == null)
217: throw new JRException(
218: "must specify collectionType property in report definition");
219: int type = Integer.parseInt(collectionType);
220: int outline = 0;
221: String outlineNumber = report.getProperty(OUTLINE_PROPERTY);
222: if (outlineNumber != null)
223: outline = Integer.parseInt(outlineNumber);
224:
225: Predicate predicate = null;
226: boolean tree = false;
227: switch (type) {
228: case PROJECT:
229: break;
230: case PROJECTS_TREE:
231: predicate = Project.instanceof Predicate();
232: tree = true;
233: break;
234: case PROJECTS_FLAT:
235: predicate = Project.instanceof Predicate();
236: break;
237: case TASKS_TREE:
238: predicate = Task.instanceof Predicate();
239: tree = true;
240: break;
241: case TASKS_FLAT:
242: predicate = Task.instanceof Predicate();
243: break;
244: case RESOURCES_TREE:
245: predicate = ResourceImpl.instanceof Predicate();
246: tree = true;
247: break;
248: case RESOURCES_FLAT:
249: predicate = ResourceImpl.instanceof Predicate();
250: break;
251: case TASKS_ASSIGNMENTS_TREE:
252: tree = true;
253: break;
254: case RESOURCES_ASSIGNMENTS_TREE:
255: tree = true;
256: break;
257: case TASKS_ASSIGNMENTS_FLAT:
258: break;
259: case RESOURCES_ASSIGNMENTS_FLAT:
260: break;
261: case ASSIGNMENTS_PROJECT_BASED:
262: predicate = Assignment.instanceof Predicate();
263: break;
264: case ASSIGNMENTS_RESOURCE_BASED:
265: predicate = Assignment.instanceof Predicate();
266: break;
267: case ASSIGNMENTS:
268: case PREDECESSORS:
269: case SUCCESSORS:
270: throw new JRException("Supreport collection type " + type
271: + " not yet implemented");
272: }
273: dataSource.setTimeBased(timeBased);
274: dataSource.setProject(project);
275: dataSource.setIterator(cacheIterator);
276: dataSource.setNodeModel(walkersNodeModel);
277: dataSource.setNodeBased(tree);
278: dataSource.setPredicate(predicate);
279: return dataSource;
280: }
281:
282: // private static NodeModel getResourceModel(Project project, int outlineNumber) {
283: // NodeModel resourceModel = project.getResourcePool().getResourceOutline(outlineNumber);
284: // if (resourceModel instanceof AssignmentNodeModel) {
285: // ((AssignmentNodeModel)resourceModel).addAssignments();
286: // }
287: // return resourceModel;
288: // }
289:
290: /* (non-Javadoc)
291: * @see net.sf.jasperreports.engine.JRDataSourceProvider#dispose(net.sf.jasperreports.engine.JRDataSource)
292: */
293: public void dispose(JRDataSource arg0) throws JRException {
294: map.clear();
295: }
296:
297: public static Object fieldValueConverterToPrimitiveType(
298: Field field, Object fieldValue) {
299: if (fieldValue == null)
300: return null;
301: if (field.isRate()) {
302: return new Double(((Rate) fieldValue).getValue());
303: } else if (field.isMoney()) {
304: return new Double(((Money) fieldValue).doubleValue());
305: } else if (field.isDurationOrWork()) {
306: return new Long(((Duration) fieldValue).longValue());
307: } else {
308: return fieldValue;
309: }
310: }
311:
312: public static JasperDesign addTimescale(JasperDesign design,
313: TimeIterator iterator, Class fieldType) {
314:
315: // extract field name
316: String baseFieldName = design.getProperty("timeBasedField");
317:
318: // get column header start position
319: JRBand pageHeader = design.getPageHeader();
320: JRElement[] elements = pageHeader.getElements();
321: int maxX = 0;
322: int maxY = 0;
323: for (int i = 0; i < elements.length; i++) {
324: maxX = (elements[i].getX() + elements[i].getWidth() > maxX) ? (elements[i]
325: .getX() + elements[i].getWidth())
326: : maxX;
327: maxY = (elements[i].getY() > maxY) ? elements[i].getY()
328: : maxY;
329: }
330:
331: JRDesignReportFont normalFont = new JRDesignReportFont();
332: normalFont.setFontName("Arial");
333: normalFont.setSize(10);
334: normalFont.setPdfFontName("Helvetica");
335:
336: try {
337: while (iterator.hasNext()) {
338:
339: // build field name from start & end
340: TimeInterval interval = iterator.next();
341: String fieldName = "TIME";
342: fieldName += interval.getStart();
343: fieldName += "_";
344: fieldName += interval.getEnd();
345: fieldName += "_" + baseFieldName;
346: System.out.println("time based field is " + fieldName);
347: // add fields
348: JRDesignField field = new JRDesignField();
349: field.setName(fieldName);
350: field.setValueClass(fieldType);
351: design.addField(field);
352:
353: System.out.println("column header is "
354: + interval.getText2());
355:
356: // add columns
357: JRDesignBand columnHeader = (JRDesignBand) design
358: .getColumnHeader();
359:
360: JRDesignStaticText staticText = new JRDesignStaticText();
361: staticText.setX(maxX);
362: staticText.setY(0);
363: staticText.setWidth(80);
364: staticText.setHeight(15);
365: staticText
366: .setTextAlignment(JRTextElement.TEXT_ALIGN_RIGHT);
367: staticText.setFont(normalFont);
368: staticText.setText(interval.getText1());
369: staticText.setPrintWhenDetailOverflows(true);
370: columnHeader.addElement(staticText);
371:
372: // add textFields
373: JRDesignBand detailBand = (JRDesignBand) design
374: .getDetail();
375:
376: JRDesignTextField textField = new JRDesignTextField();
377: textField.setX(maxX);
378: textField.setY(0);
379: textField.setWidth(80);
380: textField.setHeight(15);
381: textField
382: .setTextAlignment(JRTextElement.TEXT_ALIGN_RIGHT);
383: textField.setFont(normalFont);
384: // textField.setFont((JRReportFont)fonts.get("normalFont"));
385: JRDesignExpression expression = new JRDesignExpression();
386: expression.setValueClass(fieldType);
387: expression.setText("$F{" + fieldName + "}");
388: textField.setExpression(expression);
389: textField.setPrintWhenDetailOverflows(true);
390: detailBand.addElement(textField);
391: maxX += 80;
392: }
393:
394: } catch (JRException e) {
395: // TODO Auto-generated catch block
396: e.printStackTrace();
397: }
398: return design;
399:
400: // detailBand.addElement();
401:
402: }
403: }
|