001: package org.emforge.attachment;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.IOException;
005: import java.io.InputStream;
006: import java.util.Collection;
007: import java.util.LinkedList;
008: import java.util.List;
009:
010: import javax.jws.WebParam;
011: import javax.jws.WebService;
012:
013: import org.acegisecurity.AccessDeniedException;
014: import org.acegisecurity.userdetails.UserDetails;
015: import org.apache.commons.collections.CollectionUtils;
016: import org.apache.commons.io.IOUtils;
017: import org.apache.commons.lang.StringUtils;
018: import org.apache.commons.logging.Log;
019: import org.apache.commons.logging.LogFactory;
020: import org.emforge.AttachmentService;
021: import org.emforge.BpmService;
022: import org.emforge.EmForgeException;
023: import org.emforge.projectmanager.ProjectService;
024: import org.emforge.projectmanager.base.MilestoneDO;
025: import org.emforge.projectmanager.base.ProjectDO;
026: import org.emforge.xfer.AttachmentHistoryTO;
027: import org.emforge.xfer.AttachmentTO;
028: import org.emforge.xfer.TaskTO;
029: import org.springframework.transaction.annotation.Propagation;
030: import org.springframework.transaction.annotation.Transactional;
031:
032: import ru.emdev.EmForge.security.EmForgeUserDetails;
033: import ru.emdev.EmForge.security.UserFactory;
034: import ru.emdev.EmForge.security.web.SiteRole;
035:
036: import com.ecyrd.jspwiki.WikiContext;
037: import com.ecyrd.jspwiki.WikiEngine;
038: import com.ecyrd.jspwiki.WikiPage;
039: import com.ecyrd.jspwiki.attachment.Attachment;
040: import com.ecyrd.jspwiki.attachment.AttachmentManager;
041: import com.ecyrd.jspwiki.providers.ProviderException;
042:
043: /** Implementation of Attachments Service
044: * It is used JspWiki Engine for working with attachments
045: *
046: */
047: @WebService(endpointInterface="org.emforge.BpmService")
048: @Transactional(propagation=Propagation.REQUIRES_NEW,rollbackFor=EmForgeException.class)
049: public class AttachmentServiceImpl implements AttachmentService {
050: protected final Log logger = LogFactory.getLog(getClass());
051:
052: private WikiEngine wikiEngine;
053: private UserFactory userFactory;
054: private ProjectService projectService;
055: private BpmService bpmService;
056:
057: public void setWikiEngine(WikiEngine i_wikiEngine) {
058: wikiEngine = i_wikiEngine;
059: }
060:
061: public void setUserFactory(UserFactory i_userFactory) {
062: userFactory = i_userFactory;
063: }
064:
065: public void setProjectService(ProjectService i_projectService) {
066: projectService = i_projectService;
067: }
068:
069: public void setBpmService(BpmService i_bpmService) {
070: bpmService = i_bpmService;
071: }
072:
073: public Boolean addAttachment(String i_parentName,
074: String i_fileName, byte[] i_content, String i_comment)
075: throws EmForgeException {
076: if (StringUtils.isEmpty(i_parentName)) {
077: throw new IllegalArgumentException(
078: "parentName cannot be null or empty");
079: }
080: if (StringUtils.isEmpty(i_fileName)) {
081: throw new IllegalArgumentException(
082: "fileName cannot be null or empty");
083: }
084: if (i_content == null) {
085: throw new IllegalArgumentException(
086: "content cannot be null or empty");
087: }
088:
089: if (!canAddAttachment(i_parentName)) {
090: throw new AccessDeniedException(
091: "You are not allowed to add attachment");
092: }
093:
094: try {
095: // first check - is page exists
096: if (!wikiEngine.pageExists(i_parentName)) {
097: // create empty page - so, we will able to store attachment
098: WikiPage page = new WikiPage(wikiEngine, i_parentName);
099: WikiContext context = new WikiContext(wikiEngine, page);
100: // save empty page
101: wikiEngine.saveText(context, "");
102: }
103:
104: AttachmentManager mgr = wikiEngine.getAttachmentManager();
105: Attachment att = mgr.getAttachmentInfo(i_parentName + "/"
106: + i_fileName);
107:
108: if (att == null) {
109: att = new Attachment(wikiEngine, i_parentName,
110: i_fileName);
111: }
112:
113: UserDetails user = userFactory.getCurrentUser();
114:
115: if (user != null) {
116: att.setAuthor(user.getUsername());
117: }
118:
119: ByteArrayInputStream bais = new ByteArrayInputStream(
120: i_content);
121: wikiEngine.getAttachmentManager()
122: .storeAttachment(att, bais);
123: } catch (Exception ex) {
124: logger.error("Cannot store attachment", ex);
125: throw new EmForgeException("Cannot store attachment", ex);
126: }
127:
128: return true;
129: }
130:
131: public Boolean deleteAttachment(AttachmentTO i_attachment)
132: throws EmForgeException {
133: if (!canDeleteAttachment(i_attachment)) {
134: throw new AccessDeniedException(
135: "You are not allowed to add attachment");
136: }
137:
138: try {
139: Attachment attachment = wikiEngine.getAttachmentManager()
140: .getAttachmentInfo(
141: i_attachment.getParentName() + "/"
142: + i_attachment.getFileName());
143:
144: if (attachment != null) {
145: wikiEngine.getAttachmentManager().deleteAttachment(
146: attachment);
147: }
148: } catch (ProviderException pex) {
149: logger.error("Cannot delete attachment", pex);
150: throw new EmForgeException("Cannot delete attachment", pex);
151: }
152:
153: return true;
154: }
155:
156: public AttachmentTO getAttachment(String i_parentName,
157: String i_fileName) throws EmForgeException {
158: try {
159: Attachment attachment = wikiEngine.getAttachmentManager()
160: .getAttachmentInfo(i_parentName + "/" + i_fileName);
161:
162: if (attachment != null) {
163: return new AttachmentTransformer()
164: .transform(attachment);
165: }
166:
167: return null;
168: } catch (ProviderException pex) {
169: logger.error("Cannot get attachment", pex);
170: throw new EmForgeException("Cannot get attachment", pex);
171: }
172:
173: }
174:
175: public byte[] getAttachmentContent(AttachmentTO i_attachment)
176: throws EmForgeException {
177: try {
178: Attachment attachment = wikiEngine.getAttachmentManager()
179: .getAttachmentInfo(
180: i_attachment.getParentName() + "/"
181: + i_attachment.getFileName());
182:
183: if (attachment != null) {
184: InputStream is = wikiEngine.getAttachmentManager()
185: .getAttachmentStream(attachment);
186: return IOUtils.toByteArray(is);
187: }
188: } catch (ProviderException pex) {
189: logger.error("Cannot get attachment", pex);
190: throw new EmForgeException("Cannot get attachment", pex);
191: } catch (IOException ioex) {
192: logger.error("Cannot store attachment", ioex);
193: throw new EmForgeException("Cannot store attachment", ioex);
194: }
195:
196: return null;
197: }
198:
199: @SuppressWarnings("unchecked")
200: public AttachmentHistoryTO[] getAttachmentHistory(
201: AttachmentTO i_attachment) throws EmForgeException {
202: try {
203: List<Attachment> attachments = wikiEngine
204: .getAttachmentManager().getVersionHistory(
205: i_attachment.getParentName() + "/"
206: + i_attachment.getFileName());
207:
208: AttachmentHistoryTO[] history = new AttachmentHistoryTO[attachments
209: .size()];
210: AttachmentTransformer transformer = new AttachmentTransformer();
211: int i = 0;
212: for (Attachment attachment : attachments) {
213: AttachmentTO att = transformer.transform(attachment);
214: AttachmentHistoryTO historyEvent = new AttachmentHistoryTO();
215: historyEvent.setAttachment(att);
216:
217: historyEvent.setActor(attachment.getAuthor());
218: historyEvent.setDate(attachment.getLastModified());
219: historyEvent.setMessage(null); //TODO null for now
220: historyEvent.setLink(null); //TODO null for now
221:
222: history[i++] = historyEvent;
223: }
224:
225: return history;
226:
227: } catch (ProviderException pex) {
228: logger.error("Cannot get attachment", pex);
229: throw new EmForgeException("Cannot get attachment", pex);
230: }
231: }
232:
233: @SuppressWarnings("unchecked")
234: public AttachmentTO[] getAttachments(String i_parentName)
235: throws EmForgeException {
236: WikiPage wikiPage = new WikiPage(wikiEngine, i_parentName);
237:
238: try {
239: // get attachments
240: Collection<Attachment> attachments = wikiEngine
241: .getAttachmentManager().listAttachments(wikiPage);
242: List<AttachmentTO> result = new LinkedList<AttachmentTO>();
243:
244: // convert them to TO
245: CollectionUtils.collect(attachments,
246: new AttachmentTransformer(), result);
247:
248: return result.toArray(new AttachmentTO[result.size()]);
249: } catch (ProviderException pex) {
250: logger.error("Cannot get attachments", pex);
251: throw new EmForgeException("Cannot get attachments", pex);
252: }
253: }
254:
255: /** Is current user allowed to add attachment for specified page? */
256: public Boolean canAddAttachment(@WebParam(name="parentName")
257: String parentName) {
258: return canEditPage(parentName);
259: }
260:
261: /** Is Current user allowed to delete specified attachment */
262: public Boolean canDeleteAttachment(@WebParam(name="attachment")
263: AttachmentTO attachment) {
264: return canEditPage(attachment.getParentName());
265: }
266:
267: private Boolean canEditPage(String parentName) {
268: // admin can edit everything
269: if (isAdmin()) {
270: return true;
271: }
272:
273: // try to get project
274: ProjectDO project = projectService.getProject(parentName);
275: if (project != null) {
276: // is current user allowed to edit project?
277: return projectService.canChangeProject(project);
278: }
279: // try to get milestone
280: MilestoneDO milestone = projectService.getMilestone(parentName);
281: if (milestone != null) {
282: // is current user allowed to edit milestone?
283: return projectService.canChangeMilestone(milestone);
284: }
285:
286: // try to get task
287: Long taskId = null;
288: TaskTO task = null;
289: try {
290: taskId = Long.valueOf(parentName);
291: } catch (Exception ex) {
292: // just ignore it here
293: }
294: if (taskId != null) {
295: try {
296: task = bpmService.getTask(taskId);
297:
298: if (task != null) {
299: // only task owner - or project manager can change it
300: if (task.getOwner().equals(
301: getCurrentUser().getUsername())) {
302: return true;
303: }
304: project = projectService.getProject(task
305: .getProjectName());
306: return projectService.hasRole(project,
307: getCurrentUser(),
308: ProjectService.ROLE_MANAGER);
309: }
310: } catch (EmForgeException ex) {
311: // just ignore it here
312: }
313: }
314:
315: // ok - this is simple page - so, check for WRITER role
316: return getCurrentUser().hasRole(SiteRole.WRITER.getId());
317: }
318:
319: private EmForgeUserDetails getCurrentUser() {
320: return userFactory.getCurrentUser();
321: }
322:
323: private boolean isAdmin() {
324:
325: return getCurrentUser().hasRole(SiteRole.ADMIN.getId());
326: }
327: }
|