001: package org.contineo.web.document;
002:
003: import com.icesoft.faces.async.render.RenderManager;
004: import com.icesoft.faces.async.render.Renderable;
005: import com.icesoft.faces.component.ext.RowSelectorEvent;
006: import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState;
007: import com.icesoft.faces.webapp.xmlhttp.RenderingException;
008:
009: import org.apache.commons.logging.Log;
010: import org.apache.commons.logging.LogFactory;
011:
012: import org.contineo.core.FileBean;
013: import org.contineo.core.security.ExtMenu;
014: import org.contineo.core.security.Menu;
015: import org.contineo.core.security.MenuManager;
016: import org.contineo.core.security.UserDoc;
017: import org.contineo.core.security.dao.MenuDAO;
018: import org.contineo.core.security.dao.UserDocDAO;
019: import org.contineo.core.transfer.ZipImport;
020:
021: import org.contineo.util.Context;
022: import org.contineo.util.config.SettingsConfig;
023:
024: import org.contineo.web.SessionManagement;
025: import org.contineo.web.i18n.Messages;
026: import org.contineo.web.navigation.PageContentBean;
027: import org.contineo.web.upload.InputFileBean;
028:
029: import java.io.File;
030: import java.io.FileInputStream;
031: import java.io.InputStream;
032:
033: import java.security.AccessControlException;
034:
035: import java.util.ArrayList;
036: import java.util.Collection;
037: import java.util.HashSet;
038: import java.util.Iterator;
039: import java.util.List;
040: import java.util.Set;
041:
042: import javax.faces.application.Application;
043: import javax.faces.context.FacesContext;
044:
045: /**
046: * <p>
047: * The <code>DocumentsRecordsManager</code> class is responsible for
048: * constructing the list of <code>DocumentRecord</code> beans which will be
049: * bound to a ice:dataTable JSF component. <p/>
050: * <p>
051: * Large data sets could be handle by adding a ice:dataPaginator. Alternatively
052: * the dataTable could also be hidden and the dataTable could be added to
053: * scrollable ice:panelGroup.
054: * </p>
055: *
056: * @author Marco Meschieri
057: * @version $Id: DocumentsRecordsManager.java,v 1.1 2007/06/29 06:28:29 marco
058: * Exp $
059: * @since 3.0
060: */
061: public class DocumentsRecordsManager implements Renderable {
062: protected static Log log = LogFactory
063: .getLog(DocumentsRecordsManager.class);
064:
065: // css style related constants
066: public static final String GROUP_INDENT_STYLE_CLASS = "groupRowIndentStyle";
067: public static final String GROUP_ROW_STYLE_CLASS = "groupRowStyle";
068: public static final String CHILD_INDENT_STYLE_CLASS = "childRowIndentStyle";
069: public static final String CHILD_ROW_STYLE_CLASS = "childRowStyle";
070:
071: // toggle for expand contract
072: public static final String CONTRACT_IMAGE = "images/tableExpandable/contract.gif";
073: public static final String EXPAND_IMAGE = "images/tableExpandable/expand.gif";
074: private ArrayList<DocumentRecord> documents;
075: private boolean multipleSelection = true;
076: private int selectedDirectory;
077: private int sourceDirectory;
078: private PersistentFacesState state;
079: private RenderManager renderManager;
080:
081: // Set of selected rows
082: private Set<DocumentRecord> selection = new HashSet<DocumentRecord>();
083:
084: // A clip board of selected documents, used for example in cut&paste
085: // operations
086: private Set<DocumentRecord> clipboard = new HashSet<DocumentRecord>();
087:
088: public DocumentsRecordsManager() {
089: selectDirectory(Menu.MENUID_DOCUMENTS);
090: selection.clear();
091: clipboard.clear();
092: state = PersistentFacesState.getInstance();
093: }
094:
095: /**
096: * Changes the currently selected directory and updates the documents list.
097: *
098: * @param directoryId
099: */
100: public void selectDirectory(int directoryId) {
101: selectedDirectory = directoryId;
102: selection.clear();
103:
104: // initiate the list
105: if (documents != null) {
106: documents.clear();
107: } else {
108: documents = new ArrayList<DocumentRecord>(10);
109: }
110:
111: String username = SessionManagement.getUsername();
112: MenuDAO menuDao = (MenuDAO) Context.getInstance().getBean(
113: MenuDAO.class);
114: Collection<ExtMenu> menus = menuDao.getContainedMenus(
115: directoryId, username);
116:
117: for (ExtMenu menu : menus) {
118: if (menu.getMenuType() == Menu.MENUTYPE_FILE) {
119: DocumentRecord record;
120: Collection<ExtMenu> children = menuDao
121: .getContainedMenus(menu.getMenuId(), username);
122:
123: if (children.size() > 0) {
124: record = new DocumentRecord(menu,
125: GROUP_INDENT_STYLE_CLASS,
126: GROUP_ROW_STYLE_CLASS, EXPAND_IMAGE,
127: CONTRACT_IMAGE, documents, false);
128: } else {
129: record = new DocumentRecord(menu,
130: CHILD_INDENT_STYLE_CLASS,
131: CHILD_ROW_STYLE_CLASS);
132: }
133:
134: if (!documents.contains(record)) {
135: documents.add(record);
136: }
137:
138: for (ExtMenu childMenu : children) {
139: DocumentRecord child = new DocumentRecord(
140: childMenu, CHILD_INDENT_STYLE_CLASS,
141: CHILD_ROW_STYLE_CLASS);
142: record.addChildRecord(child);
143: }
144: }
145: }
146: }
147:
148: /**
149: * Cleans up the resources used by this class. This method could be called
150: * when a session destroyed event is called.
151: */
152: public void dispose() {
153: documents.clear();
154: }
155:
156: /**
157: * Gets the list of DocumentRecord which will be used by the ice:dataTable
158: * component.
159: *
160: * @return array list of parent DocumentRecord
161: */
162: public ArrayList getDocuments() {
163: return documents;
164: }
165:
166: public boolean isMultipleSelection() {
167: return multipleSelection;
168: }
169:
170: public void setMultipleSelection(boolean multiple) {
171: this .multipleSelection = multiple;
172: }
173:
174: public void selectRow(RowSelectorEvent e) {
175: DocumentRecord record = documents.get(e.getRow());
176:
177: if (e.isSelected() || !selection.contains(record)) {
178: selection.add(record);
179: } else if (!e.isSelected() || selection.contains(record)) {
180: selection.remove(record);
181: }
182: }
183:
184: public void refresh() {
185: selectDirectory(selectedDirectory);
186: }
187:
188: public int getClipboardSize() {
189: return clipboard.size();
190: }
191:
192: public int getCount() {
193: if (documents == null) {
194: return 0;
195: } else {
196: return documents.size();
197: }
198: }
199:
200: /**
201: * Deletes all selected documents
202: */
203: public String deleteSelected() {
204: if (SessionManagement.isValid()) {
205: if (!selection.isEmpty()) {
206: MenuManager manager = (MenuManager) Context
207: .getInstance().getBean(MenuManager.class);
208:
209: for (DocumentRecord record : selection) {
210: try {
211: manager.deleteMenu(record.getMenu(),
212: SessionManagement.getUsername());
213: Messages
214: .addLocalizedInfo("msg.action.deleteitem");
215: } catch (AccessControlException e) {
216: Messages
217: .addLocalizedError("document.write.nopermission");
218: } catch (Exception e) {
219: Messages
220: .addLocalizedInfo("errors.action.deleteitem");
221: }
222: }
223:
224: refresh();
225: } else {
226: Messages.addLocalizedWarn("noselection");
227: }
228:
229: return null;
230: } else {
231: return "login";
232: }
233: }
234:
235: /**
236: * Trims all selected documents
237: */
238: public String trimSelected() {
239: if (SessionManagement.isValid()) {
240: if (!selection.isEmpty()) {
241: sourceDirectory = selectedDirectory;
242: clipboard.clear();
243:
244: for (DocumentRecord record : selection) {
245: clipboard.add(record);
246: }
247:
248: refresh();
249: } else {
250: Messages.addLocalizedWarn("noselection");
251: }
252:
253: return null;
254: } else {
255: return "login";
256: }
257: }
258:
259: /**
260: * Paste previously trimmed documents into the current directory
261: */
262: public String paste() {
263: if (SessionManagement.isValid()) {
264: if (!clipboard.isEmpty()) {
265: String username = SessionManagement.getUsername();
266: MenuDAO menuDao = (MenuDAO) Context.getInstance()
267: .getBean(MenuDAO.class);
268:
269: if (menuDao.isWriteEnable(selectedDirectory, username)) {
270: try {
271: DocumentNavigation navigation = ((DocumentNavigation) FacesContext
272: .getCurrentInstance().getApplication()
273: .createValueBinding(
274: "#{documentNavigation}")
275: .getValue(
276: FacesContext
277: .getCurrentInstance()));
278:
279: for (DocumentRecord record : clipboard) {
280: Menu menu = menuDao.findByPrimaryKey(record
281: .getMenuId());
282:
283: if (!menuDao.isWriteEnable(
284: menu.getMenuId(), username)) {
285: throw new AccessControlException("");
286: }
287:
288: menu.setMenuParent(selectedDirectory);
289: menuDao.store(menu);
290:
291: // Update navigation tree
292: Directory destination = navigation
293: .getDirectory(selectedDirectory);
294: destination
295: .setCount(destination.getCount() + 1);
296:
297: Directory source = navigation
298: .getDirectory(sourceDirectory);
299: source.setCount(source.getCount() - 1);
300: }
301: } catch (AccessControlException e) {
302: Messages
303: .addLocalizedWarn("document.write.nopermission");
304: } catch (Exception e) {
305: Messages
306: .addLocalizedInfo("errors.action.movedocument");
307: }
308:
309: clipboard.clear();
310: } else {
311: Messages
312: .addLocalizedWarn("document.write.nopermission");
313: }
314:
315: refresh();
316: }
317:
318: return null;
319: } else {
320: return "login";
321: }
322: }
323:
324: /**
325: * Shows the zip upload form
326: */
327: public String startZipUpload() {
328: Application application = FacesContext.getCurrentInstance()
329: .getApplication();
330: DocumentNavigation documentNavigation = ((DocumentNavigation) application
331: .createValueBinding("#{documentNavigation}").getValue(
332: FacesContext.getCurrentInstance()));
333:
334: if (SessionManagement.isValid()) {
335: try {
336: MenuDAO mdao = (MenuDAO) Context.getInstance().getBean(
337: MenuDAO.class);
338: String username = SessionManagement.getUsername();
339: Directory dir = documentNavigation.getSelectedDir();
340: int parentId = dir.getMenuId();
341:
342: if (mdao.isWriteEnable(parentId, username)) {
343: documentNavigation
344: .setSelectedPanel(new PageContentBean(
345: "zipImport"));
346: } else {
347: Messages
348: .addLocalizedError("document.write.nopermission");
349: }
350:
351: documentNavigation
352: .setSelectedPanel(new PageContentBean(
353: "zipUpload"));
354: } catch (Exception e) {
355: log.error(e.getMessage(), e);
356: Messages.addError(e.getMessage());
357: }
358: } else {
359: return "login";
360: }
361:
362: return null;
363: }
364:
365: /**
366: * Imports the zip content in the current directory
367: */
368: public String uploadZip() {
369: if (SessionManagement.isValid()) {
370: try {
371: String username = SessionManagement.getUsername();
372:
373: Application application = FacesContext
374: .getCurrentInstance().getApplication();
375: InputFileBean inputFile = ((InputFileBean) application
376: .createValueBinding("#{inputFile}").getValue(
377: FacesContext.getCurrentInstance()));
378:
379: File file = inputFile.getFile();
380: String zipLanguage = inputFile.getLanguage();
381:
382: MenuDAO menuDao = (MenuDAO) Context.getInstance()
383: .getBean(MenuDAO.class);
384: Menu parent = menuDao
385: .findByPrimaryKey(selectedDirectory);
386: SettingsConfig conf = (SettingsConfig) Context
387: .getInstance().getBean(SettingsConfig.class);
388: String path = conf.getValue("userdir");
389:
390: if (!path.endsWith(File.pathSeparator)) {
391: path += File.pathSeparator;
392: }
393:
394: path += (username + File.pathSeparator);
395: FileBean.createDir(path);
396:
397: InputStream stream = new FileInputStream(file);
398: FileBean.writeFile(stream, path + file.getName());
399: stream.close();
400:
401: ZipImport importer = new ZipImport();
402: importer.process(path + file.getName(), zipLanguage,
403: parent, username);
404: FileBean.deleteFile(path + file.getName());
405: Messages.addLocalizedInfo("msg.action.importfolder");
406:
407: DocumentNavigation documentNavigation = ((DocumentNavigation) application
408: .createValueBinding("#{documentNavigation}")
409: .getValue(FacesContext.getCurrentInstance()));
410: documentNavigation.refresh();
411: documentNavigation
412: .setSelectedPanel(new PageContentBean(
413: "documents"));
414:
415: if (renderManager != null) {
416: renderManager.requestRender(this );
417: }
418: } catch (Throwable e) {
419: log.error(e.getMessage(), e);
420: Messages.addError(e.getMessage());
421: }
422: } else {
423: return "login";
424: }
425:
426: return null;
427: }
428:
429: /**
430: * Retrieves the list of last accessed documents from the database
431: */
432: public List<DocumentRecord> getLastDocs() {
433: List<DocumentRecord> lastdocs = new ArrayList<DocumentRecord>();
434:
435: if (SessionManagement.isValid()) {
436: try {
437: String username = SessionManagement.getUsername();
438: UserDocDAO uddao = (UserDocDAO) Context.getInstance()
439: .getBean(UserDocDAO.class);
440: Collection userdocs = uddao.findByUserName(username);
441: Iterator iter = userdocs.iterator();
442: MenuDAO mdao = (MenuDAO) Context.getInstance().getBean(
443: MenuDAO.class);
444:
445: while (iter.hasNext()) {
446: UserDoc userdoc = (UserDoc) iter.next();
447: Menu m = mdao.findByPrimaryKey(userdoc.getMenuId());
448: ExtMenu menu = new ExtMenu(m);
449: lastdocs.add(new DocumentRecord(menu,
450: GROUP_INDENT_STYLE_CLASS,
451: GROUP_ROW_STYLE_CLASS));
452: }
453: } catch (Exception e) {
454: log.error(e.getMessage(), e);
455: }
456: }
457:
458: return lastdocs;
459: }
460:
461: public PersistentFacesState getState() {
462: return state;
463: }
464:
465: public void renderingException(RenderingException renderingException) {
466: renderingException.printStackTrace();
467: }
468:
469: public RenderManager getRenderManager() {
470: return renderManager;
471: }
472:
473: public void setRenderManager(RenderManager renderManager) {
474: this.renderManager = renderManager;
475: }
476: }
|