View Javadoc

1   /*******************************************************************************
2    *  Imixs Workflow 
3    *  Copyright (C) 2001, 2011 Imixs Software Solutions GmbH,  
4    *  http://www.imixs.com
5    *  
6    *  This program is free software; you can redistribute it and/or 
7    *  modify it under the terms of the GNU General Public License 
8    *  as published by the Free Software Foundation; either version 2 
9    *  of the License, or (at your option) any later version.
10   *  
11   *  This program is distributed in the hope that it will be useful, 
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
14   *  General Public License for more details.
15   *  
16   *  You can receive a copy of the GNU General Public
17   *  License at http://www.gnu.org/licenses/gpl.html
18   *  
19   *  Project: 
20   *  	http://www.imixs.org
21   *  	http://java.net/projects/imixs-workflow
22   *  
23   *  Contributors:  
24   *  	Imixs Software Solutions GmbH - initial API and implementation
25   *  	Ralph Soika - Software Developer
26   *******************************************************************************/
27  
28  package org.imixs.workflow.jee.ejb;
29  
30  import java.util.Collection;
31  import java.util.Iterator;
32  import java.util.Map;
33  
34  import javax.annotation.security.DeclareRoles;
35  import javax.annotation.security.RolesAllowed;
36  import javax.ejb.EJB;
37  import javax.ejb.LocalBean;
38  import javax.ejb.Stateless;
39  
40  import org.imixs.workflow.ItemCollection;
41  import org.imixs.workflow.exceptions.AccessDeniedException;
42  
43  /**
44   * The ReportService supports methods to create, process and find report
45   * instances.
46   * 
47   * A Report Entity is identified by its name represented by the attribute
48   * 'txtname' So a ReportService Implementation should ensure that txtname is a
49   * unique key for the report entity.
50   * 
51   * Also each report entity holds a EQL Query in the attribute "txtquery". this
52   * eql statement will be processed by the processQuery method and should return
53   * a collection of entities defined by the query.
54   * 
55   * 
56   * @author Ralph Soika
57   * 
58   */
59  
60  @DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS",
61  		"org.imixs.ACCESSLEVEL.READERACCESS",
62  		"org.imixs.ACCESSLEVEL.AUTHORACCESS",
63  		"org.imixs.ACCESSLEVEL.EDITORACCESS",
64  		"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
65  @RolesAllowed({ "org.imixs.ACCESSLEVEL.NOACCESS",
66  		"org.imixs.ACCESSLEVEL.READERACCESS",
67  		"org.imixs.ACCESSLEVEL.AUTHORACCESS",
68  		"org.imixs.ACCESSLEVEL.EDITORACCESS",
69  		"org.imixs.ACCESSLEVEL.MANAGERACCESS" })
70  @Stateless
71  @LocalBean
72  public class ReportService {
73  
74  	@EJB
75  	EntityService entityService;
76  
77  	/**
78  	 * Returns a Report Entity identified by the attribute txtname
79  	 * 
80  	 * @param aReportName
81  	 *            - name of the report
82  	 * @return ItemCollection representing the Report
83  	 * @throws Exception
84  	 */
85  	public ItemCollection getReport(String aReportName) {
86  
87  		ItemCollection itemCol = findReport(aReportName);
88  		return itemCol;
89  	}
90  
91  	/**
92  	 * This method returns a collection of reports (ItemCollection). The method
93  	 * should return a subset of a collection if the start and count parameters
94  	 * differ form the value -1.
95  	 * 
96  	 * The method returns only ItemCollections the call has sufficient read
97  	 * access for.
98  	 */
99  	public Collection<ItemCollection> getReportList(int startpos, int count) {
100 		String sQuery = null;
101 		sQuery = "SELECT";
102 		sQuery += " wi FROM Entity as wi " + "WHERE wi.type = 'ReportEntity'";
103 
104 		Collection<ItemCollection> col = entityService.findAllEntities(sQuery,
105 				startpos, count);
106 
107 		return col;
108 	}
109 
110 	/**
111 	 * updates a Entity Report Object. The Entity representing a report must
112 	 * have at least the attributes : txtQuery, numMaxCount, numStartPost,
113 	 * txtName.
114 	 * 
115 	 * txtName is the unique key to be use to get a query.
116 	 * 
117 	 * The method checks if a report with the same key allready exists. If so
118 	 * this report will be updated. If no report exists the new report will be
119 	 * created
120 	 * 
121 	 * @param report
122 	 * @throws InvalidItemValueException
123 	 * @throws AccessDeniedException
124 	 * 
125 	 */
126 	public void updateReport(ItemCollection aReport)
127 			throws  AccessDeniedException {
128 
129 		aReport.replaceItemValue("type", "ReportEntity");
130 
131 		// check if Report has a $uniqueid
132 		String sUniqueID = aReport.getItemValueString("$uniqueID");
133 		// if not try to find report by its name
134 		if ("".equals(sUniqueID)) {
135 			String sReportName = aReport.getItemValueString("txtName");
136 			// try to find existing Report by name.
137 			ItemCollection oldReport = findReport(sReportName);
138 			if (oldReport != null) {
139 				// old Report exists allready
140 				aReport = updateReport(aReport, oldReport);
141 			}
142 		}
143 
144 		entityService.save(aReport);
145 	}
146 
147 	/**
148 	 * Process a QueryEntity Object identified by the attribute txtname. All
149 	 * informations about the Query are stored in the QueryObject these
150 	 * attributes are: txtQuery, numMaxCount, numStartPost, txtName
151 	 * 
152 	 * 
153 	 * @param aID
154 	 * @return
155 	 * @throws Exception
156 	 */
157 	public Collection<ItemCollection> processReport(String aReportName) {
158 		// Load Query Object
159 		ItemCollection itemCol = findReport(aReportName);
160 		String sQuery = itemCol.getItemValueString("txtQuery");
161 		int istartPos = itemCol.getItemValueInteger("numStartPos");
162 		int imaxcount = itemCol.getItemValueInteger("numMaxCount");
163 		if (imaxcount == 0)
164 			imaxcount = -1;
165 
166 		Collection<ItemCollection> col = entityService.findAllEntities(sQuery,
167 				istartPos, imaxcount);
168 		return col;
169 	}
170 
171 	/**
172 	 * helper method returns a QueryEntity identified by its name or uniqueID
173 	 * 
174 	 * @param aid
175 	 * @return
176 	 */
177 	private ItemCollection findReport(String aid) {
178 		String sQuery = null;
179 		sQuery = "SELECT";
180 		sQuery += " wi FROM Entity as wi " + "JOIN wi.textItems as i "
181 				+ "WHERE (wi.id='" + aid + "') OR "
182 				+ "(i.itemName = 'txtname' " + "AND i.itemValue = '" + aid
183 				+ "') " + " AND wi.type = 'ReportEntity'";
184 
185 		Collection<ItemCollection> col = entityService.findAllEntities(sQuery,
186 				0, 1);
187 		if (col.size() > 0)
188 			return col.iterator().next();
189 		else
190 			return null;
191 	}
192 
193 	/**
194 	 * This methode updates the a itemCollection with the attributes supported
195 	 * by another itemCollection without the $uniqueid
196 	 * 
197 	 * @param aworkitem
198 	 * 
199 	 */
200 	private ItemCollection updateReport(ItemCollection newReport,
201 			ItemCollection oldReport)  {
202 		Iterator iter = newReport.getAllItems().entrySet().iterator();
203 		while (iter.hasNext()) {
204 			Map.Entry mapEntry = (Map.Entry) iter.next();
205 			String sName = mapEntry.getKey().toString();
206 			Object o = mapEntry.getValue();
207 			if (isValidAttributeName(sName)) {
208 				oldReport.replaceItemValue(sName, o);
209 			}
210 		}
211 		return oldReport;
212 	}
213 
214 	/**
215 	 * This method returns true if the attribute name can be updated by a
216 	 * client. Workflow Attributes are not valid
217 	 * 
218 	 * @param aName
219 	 * @return
220 	 */
221 	private boolean isValidAttributeName(String aName) {
222 		if ("namcreator".equalsIgnoreCase(aName))
223 			return false;
224 		if ("$created".equalsIgnoreCase(aName))
225 			return false;
226 		if ("$modified".equalsIgnoreCase(aName))
227 			return false;
228 		if ("$uniqueID".equalsIgnoreCase(aName))
229 			return false;
230 		if ("$isAuthor".equalsIgnoreCase(aName))
231 			return false;
232 
233 		return true;
234 
235 	}
236 }