001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2007
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.war.beans.admin.structure;
034:
035: import com.flexive.faces.FxJsfUtils;
036: import com.flexive.faces.messages.FxFacesMsgErr;
037: import com.flexive.shared.CacheAdmin;
038: import com.flexive.shared.EJBLookup;
039: import com.flexive.shared.security.Role;
040: import com.flexive.shared.exceptions.FxApplicationException;
041: import com.flexive.shared.structure.*;
042: import com.flexive.shared.value.FxString;
043: import com.flexive.war.beans.admin.structure.OptionWrapper.WrappedOption;
044: import com.flexive.war.javascript.tree.StructureTreeWriter;
045: import org.apache.commons.lang.StringUtils;
046: import org.apache.commons.logging.Log;
047: import org.apache.commons.logging.LogFactory;
048:
049: import java.util.List;
050: import java.util.ArrayList;
051:
052: /**
053: * Bean behind groupAssignmentEditor.xhtml, groupEditor.xhtml and groupOptionEditor to
054: * edit FxGroupAssignment and FxGroup objects
055: *
056: * @author Gerhard Glos (gerhard.glos@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
057: */
058:
059: public class GroupEditorBean {
060:
061: private static final Log LOG = LogFactory
062: .getLog(GroupEditorBean.class);
063: private FxGroupEdit group = null;
064: private FxGroupAssignmentEdit assignment = null;
065: private String assignmentMinMul = null;
066: private String assignmentMaxMul = null;
067: private String groupMinMul = null;
068: private String groupMaxMul = null;
069: private String groupOptionValue = null;
070: private String groupOptionKey = null;
071: private boolean groupOptionOverridable = true;
072: private String assignmentOptionValue = null;
073: private String assignmentOptionKey = null;
074: private OptionWrapper optionWrapper = null;
075: private WrappedOption optionFiler = null;
076: private FxType parentType = null;
077: private String parentXPath = null;
078: private int defaultMultiplicity = -1;
079: //checker for the editMode: if not in edit mode,
080: // save and delete buttons are not rendered by the gui
081: private boolean editMode = false;
082: //checker if current user may edit the property
083: private boolean structureManagement = false;
084:
085: public String getParseRequestParameters() {
086: try {
087: String action = FxJsfUtils.getParameter("action");
088: if (StringUtils.isBlank(action)) {
089: return null;
090: } else if ("openInstance".equals(action)) {
091: editMode = false;
092: long propId = FxJsfUtils.getLongParameter("id", -1);
093: assignment = ((FxGroupAssignment) CacheAdmin
094: .getEnvironment().getAssignment(propId))
095: .asEditable();
096: group = assignment.getGroupEdit();
097: initEditing();
098: } else if ("editInstance".equals(action)) {
099: editMode = true;
100: long propId = FxJsfUtils.getLongParameter("id", -1);
101: assignment = ((FxGroupAssignment) CacheAdmin
102: .getEnvironment().getAssignment(propId))
103: .asEditable();
104: group = assignment.getGroupEdit();
105: initEditing();
106: } else if ("createGroup".equals(action)) {
107: editMode = true;
108: assignment = null;
109: parentXPath = null;
110: parentType = null;
111:
112: long id = FxJsfUtils.getLongParameter("id");
113: String nodeType = FxJsfUtils.getParameter("nodeType");
114:
115: parentXPath = "/";
116:
117: if (StructureTreeWriter.DOC_TYPE_TYPE.equals(nodeType)
118: || StructureTreeWriter.DOC_TYPE_TYPE_RELATION
119: .equals(nodeType)) {
120: parentType = CacheAdmin.getEnvironment()
121: .getType(id);
122: }
123:
124: if (StructureTreeWriter.DOC_TYPE_GROUP.equals(nodeType)) {
125: FxGroupAssignment ga = (FxGroupAssignment) CacheAdmin
126: .getEnvironment().getAssignment(id);
127: parentType = ga.getAssignedType();
128: parentXPath = ga.getXPath();
129: }
130:
131: group = FxGroupEdit.createNew("NEWGROUP", new FxString(
132: ""), new FxString(""), false,
133: FxMultiplicity.MULT_0_1);
134: initNewGroupEditing();
135: } else if ("assignGroup".equals(action)) {
136: editMode = false;
137: structureManagement = FxJsfUtils.getRequest()
138: .getUserTicket().isInRole(
139: Role.StructureManagement);
140: if (structureManagement) {
141: long id = FxJsfUtils.getLongParameter("id");
142: String nodeType = FxJsfUtils
143: .getParameter("nodeType");
144:
145: parentXPath = "/";
146:
147: if (StructureTreeWriter.DOC_TYPE_TYPE
148: .equals(nodeType)
149: || StructureTreeWriter.DOC_TYPE_TYPE_RELATION
150: .equals(nodeType)) {
151: parentType = CacheAdmin.getEnvironment()
152: .getType(id);
153: }
154:
155: if (StructureTreeWriter.DOC_TYPE_GROUP
156: .equals(nodeType)) {
157: FxGroupAssignment ga = (FxGroupAssignment) CacheAdmin
158: .getEnvironment().getAssignment(id);
159: parentType = ga.getAssignedType();
160: parentXPath = ga.getXPath();
161: }
162: long assignmentId = EJBLookup.getAssignmentEngine()
163: .save(
164: FxGroupAssignmentEdit.createNew(
165: assignment, parentType,
166: assignment.getAlias(),
167: parentXPath), true);
168: StructureTreeControllerBean s = (StructureTreeControllerBean) FxJsfUtils
169: .getManagedBean("structureTreeControllerBean");
170: s
171: .addAction(
172: StructureTreeControllerBean.ACTION_RELOAD_SELECT_ASSIGNMENT,
173: assignmentId, "");
174: }
175: }
176:
177: } catch (Throwable t) {
178: LOG.error("Failed to parse request parameters: "
179: + t.getMessage(), t);
180: new FxFacesMsgErr(t).addToContext();
181: }
182:
183: return null;
184: }
185:
186: public void toggleEditMode() {
187: editMode = !editMode;
188: }
189:
190: public boolean getEditMode() {
191: return editMode;
192: }
193:
194: public boolean isStructureManagement() {
195: return structureManagement;
196: }
197:
198: public boolean isSystemInternal() {
199: return assignment != null && assignment.isSystemInternal();
200: }
201:
202: /**
203: * initializes variables and does workarounds so editing
204: * of an existing group and group assignment is possible via the webinterface
205: */
206: private void initEditing() {
207: structureManagement = FxJsfUtils.getRequest().getUserTicket()
208: .isInRole(Role.StructureManagement);
209: defaultMultiplicity = assignment.getDefaultMultiplicity();
210: assignmentMinMul = FxMultiplicity.getIntToString(assignment
211: .getMultiplicity().getMin());
212: assignmentMaxMul = FxMultiplicity.getIntToString(assignment
213: .getMultiplicity().getMax());
214: groupMinMul = FxMultiplicity.getIntToString(group
215: .getMultiplicity().getMin());
216: groupMaxMul = FxMultiplicity.getIntToString(group
217: .getMultiplicity().getMax());
218: optionWrapper = new OptionWrapper(group.getOptions(),
219: assignment.getOptions(), false);
220: }
221:
222: /**
223: * initializes variables necessarry for creating a new group via the web interface.
224: * during the creation process, new groups don't have assignments yet.
225: */
226: private void initNewGroupEditing() {
227: structureManagement = FxJsfUtils.getRequest().getUserTicket()
228: .isInRole(Role.StructureManagement);
229: group.setOverrideMultiplicity(true);
230: groupMinMul = FxMultiplicity.getIntToString(group
231: .getMultiplicity().getMin());
232: groupMaxMul = FxMultiplicity.getIntToString(group
233: .getMultiplicity().getMax());
234: optionWrapper = new OptionWrapper(group.getOptions(), null,
235: false);
236: }
237:
238: /**
239: * Return if the groupMode may be changed.
240: * This is the case for groups where no content exists yet.
241: *
242: * @return if the groupMode may be changed
243: */
244: public boolean isMayChangeGroupMode() {
245: try {
246: return EJBLookup.getAssignmentEngine()
247: .getAssignmentInstanceCount(assignment.getId()) == 0;
248: } catch (Throwable t) {
249: new FxFacesMsgErr(t).addToContext();
250: //fallback
251: return false;
252: }
253: }
254:
255: /**
256: * If the assignment is derived, return the base assignments XPath
257: *
258: * @return the base assignments XPath if derived
259: */
260: public String getBaseAssignmentXPath() {
261: if (assignment.isDerivedAssignment())
262: return CacheAdmin.getEnvironment().getAssignment(
263: assignment.getBaseAssignmentId()).getXPath();
264: else
265: return "";
266: }
267:
268: public String getAssignmentAlias() {
269: return assignment.getAlias();
270: }
271:
272: public void setAssignmentAlias(String a) {
273: try {
274: assignment.setAlias(a);
275: } catch (Throwable t) {
276: new FxFacesMsgErr(t).addToContext();
277: }
278: }
279:
280: public int getAssignmentDefaultMultiplicity() {
281: return this .defaultMultiplicity;
282: }
283:
284: public void setAssignmentDefaultMultiplicity(int defaultMultiplicity) {
285: this .defaultMultiplicity = defaultMultiplicity;
286: }
287:
288: public boolean isAssignmentEnabled() {
289: return assignment.isEnabled();
290: }
291:
292: public void setAssignmentEnabled(boolean e) {
293: assignment.setEnabled(e);
294: }
295:
296: public FxString getAssignmentHint() {
297: return assignment.getHint();
298: }
299:
300: public void setAssignmentHint(FxString h) {
301: assignment.setHint(h);
302: }
303:
304: public FxString getAssignmentLabel() {
305: return assignment.getLabel();
306: }
307:
308: public void setAssignmentLabel(FxString l) {
309: assignment.setLabel(l);
310: }
311:
312: public GroupMode getAssignmentMode() {
313: return assignment.getMode();
314: }
315:
316: public void setAssignmentMode(GroupMode m) {
317: assignment.setMode(m);
318: }
319:
320: public FxGroupEdit getGroup() {
321: return group;
322: }
323:
324: public void setGroup(FxGroupEdit group) {
325: this .group = group;
326: }
327:
328: public FxGroupAssignmentEdit getAssignment() {
329: return assignment;
330: }
331:
332: public void setAssignment(FxGroupAssignmentEdit assignment) {
333: this .assignment = assignment;
334: }
335:
336: public String getAssignmentMinMul() {
337: return assignmentMinMul;
338: }
339:
340: public void setAssignmentMinMul(String assignmentMinMul) {
341: this .assignmentMinMul = assignmentMinMul;
342: }
343:
344: public String getAssignmentMaxMul() {
345: return assignmentMaxMul;
346: }
347:
348: public void setAssignmentMaxMul(String assignmentMaxMul) {
349: this .assignmentMaxMul = assignmentMaxMul;
350: }
351:
352: public String getGroupMaxMul() {
353: return groupMaxMul;
354: }
355:
356: public void setGroupMaxMul(String groupMaxMul) {
357: this .groupMaxMul = groupMaxMul;
358: }
359:
360: public String getGroupMinMul() {
361: return groupMinMul;
362: }
363:
364: public void setGroupMinMul(String groupMinMul) {
365: this .groupMinMul = groupMinMul;
366: }
367:
368: public GroupMode getGroupAssignmentGroupMode() {
369: return group.getAssignmentGroupMode();
370: }
371:
372: public void setGroupAssignmentGroupMode(GroupMode gm) {
373: try {
374: group.setAssignmentGroupMode(gm);
375: } catch (Throwable t) {
376: new FxFacesMsgErr(t).addToContext();
377: }
378: }
379:
380: public FxString getGroupHint() {
381: return group.getHint();
382: }
383:
384: public void setGroupHint(FxString h) {
385: group.setHint(h);
386: }
387:
388: public FxString getGroupLabel() {
389: return group.getLabel();
390: }
391:
392: public void setGroupLabel(FxString l) {
393: group.setLabel(l);
394: }
395:
396: public String getGroupName() {
397: return group.getName();
398: }
399:
400: public void setGroupName(String n) {
401: group.setName(n);
402: }
403:
404: public boolean isGroupOverrideBaseMultiplicity() {
405: return group.mayOverrideBaseMultiplicity();
406: }
407:
408: public void setGroupOverrideBaseMultiplicity(boolean b) {
409: if (group.mayOverrideBaseMultiplicity() && !b) {
410: assignmentMinMul = groupMinMul;
411: assignmentMaxMul = groupMaxMul;
412: }
413: group.setOverrideMultiplicity(b);
414: }
415:
416: /**
417: * Apply changes to the group and the assignment and forward them to DB
418: */
419: public void saveChanges() {
420: if (FxJsfUtils.getRequest().getUserTicket().isInRole(
421: Role.StructureManagement)) {
422: try {
423: applyGroupChanges();
424: saveAssignmentChanges();
425: EJBLookup.getAssignmentEngine().save(group);
426: StructureTreeControllerBean s = (StructureTreeControllerBean) FxJsfUtils
427: .getManagedBean("structureTreeControllerBean");
428: s
429: .addAction(
430: StructureTreeControllerBean.ACTION_RENAME_SELECT_ASSIGNMENT,
431: assignment.getId(), assignment
432: .getDisplayName());
433: } catch (Throwable t) {
434: new FxFacesMsgErr(t).addToContext();
435: }
436: } else
437: new FxFacesMsgErr(new FxApplicationException(
438: "ex.role.notInRole", "StructureManagement"))
439: .addToContext();
440: }
441:
442: /**
443: * Save a newly created group to DB
444: */
445: public void createGroup() {
446: if (FxJsfUtils.getRequest().getUserTicket().isInRole(
447: Role.StructureManagement)) {
448: try {
449: applyGroupChanges();
450: long assignmentId;
451: if (parentType != null)
452: assignmentId = EJBLookup.getAssignmentEngine()
453: .createGroup(parentType.getId(), group,
454: parentXPath);
455: else
456: assignmentId = EJBLookup.getAssignmentEngine()
457: .createGroup(group, parentXPath);
458: StructureTreeControllerBean s = (StructureTreeControllerBean) FxJsfUtils
459: .getManagedBean("structureTreeControllerBean");
460: s
461: .addAction(
462: StructureTreeControllerBean.ACTION_RELOAD_SELECT_ASSIGNMENT,
463: assignmentId, "");
464:
465: } catch (Throwable t) {
466: new FxFacesMsgErr(t).addToContext();
467: }
468: } else
469: new FxFacesMsgErr(new FxApplicationException(
470: "ex.role.notInRole", "StructureManagement"))
471: .addToContext();
472: }
473:
474: /**
475: * Apply all changes to the group assignment which are still cached in
476: * the view (options, multiplicity, label) and forward them to DB
477: *
478: * @throws FxApplicationException if the label is invalid
479: */
480: private void saveAssignmentChanges() throws FxApplicationException {
481: //delete current options
482: while (!assignment.getOptions().isEmpty()) {
483: String key = assignment.getOptions().get(0).getKey();
484: assignment.clearOption(key);
485: }
486: List<FxStructureOption> newAssignmentOptions = optionWrapper
487: .asFxStructureOptionList(optionWrapper
488: .getAssignmentOptions());
489: for (FxStructureOption o : newAssignmentOptions) {
490: assignment.setOption(o.getKey(), o.getValue());
491: }
492:
493: if (assignment.getLabel().getIsEmpty()) {
494: throw new FxApplicationException(
495: "ex.structureEditor.noLabel");
496: }
497: int min = FxMultiplicity.getStringToInt(assignmentMinMul);
498: int max = FxMultiplicity.getStringToInt(assignmentMaxMul);
499:
500: if (!isSystemInternal()
501: || FxJsfUtils.getRequest().getUserTicket().isInRole(
502: Role.GlobalSupervisor)) {
503: if (group.mayOverrideBaseMultiplicity()) {
504: FxJsfUtils.checkMultiplicity(min, max);
505: assignment
506: .setMultiplicity(new FxMultiplicity(min, max));
507: }
508: assignment.setDefaultMultiplicity(this .defaultMultiplicity);
509: EJBLookup.getAssignmentEngine().save(assignment, false);
510: }
511: }
512:
513: /**
514: * Apply all changes to the group assignment which are still cached in
515: * the view (options, multiplicity, label) and forward them to DB
516: *
517: * @throws FxApplicationException if the label is invalid
518: */
519: private void applyGroupChanges() throws FxApplicationException {
520: if (group.getLabel().getIsEmpty()) {
521: throw new FxApplicationException(
522: "ex.structureEditor.noLabel");
523: }
524: FxMultiplicity grpMul = new FxMultiplicity(FxMultiplicity
525: .getStringToInt(groupMinMul), FxMultiplicity
526: .getStringToInt(groupMaxMul));
527:
528: FxJsfUtils.checkMultiplicity(grpMul.getMin(), grpMul.getMax());
529:
530: while (!group.getOptions().isEmpty()) {
531: String key = group.getOptions().get(0).getKey();
532: group.clearOption(key);
533: }
534:
535: List<FxStructureOption> newGroupOptions = optionWrapper
536: .asFxStructureOptionList(optionWrapper
537: .getStructureOptions());
538: for (FxStructureOption o : newGroupOptions) {
539: group.setOption(o.getKey(), o.isOverrideable(), o
540: .getValue());
541: }
542:
543: if (!isSystemInternal()
544: || FxJsfUtils.getRequest().getUserTicket().isInRole(
545: Role.GlobalSupervisor))
546: group.setMultiplicity(grpMul);
547: }
548:
549: public String showGroupOptionEditor() {
550: return "groupOptionEditor";
551: }
552:
553: public String showGroupEditor() {
554: return "groupEditor";
555: }
556:
557: public String showGroupAssignmentEditor() {
558: return "groupAssignmentEditor";
559: }
560:
561: public OptionWrapper getOptionWrapper() {
562: return optionWrapper;
563: }
564:
565: public WrappedOption getOptionFiler() {
566: return optionFiler;
567: }
568:
569: public void setOptionFiler(WrappedOption o) {
570: optionFiler = o;
571: }
572:
573: public String getGroupOptionValue() {
574: return groupOptionValue;
575: }
576:
577: public void setGroupOptionValue(String groupOptionValue) {
578: this .groupOptionValue = groupOptionValue;
579: }
580:
581: public String getGroupOptionKey() {
582: return groupOptionKey;
583: }
584:
585: public void setGroupOptionKey(String groupOptionKey) {
586: this .groupOptionKey = groupOptionKey;
587: }
588:
589: public boolean isGroupOptionOverridable() {
590: return groupOptionOverridable;
591: }
592:
593: public void setGroupOptionOverridable(boolean groupOptionOverridable) {
594: this .groupOptionOverridable = groupOptionOverridable;
595: }
596:
597: public String getAssignmentOptionValue() {
598: return assignmentOptionValue;
599: }
600:
601: public void setAssignmentOptionValue(String assignmentOptionValue) {
602: this .assignmentOptionValue = assignmentOptionValue;
603: }
604:
605: public String getAssignmentOptionKey() {
606: return assignmentOptionKey;
607: }
608:
609: public void setAssignmentOptionKey(String assignmentOptionKey) {
610: this .assignmentOptionKey = assignmentOptionKey;
611: }
612:
613: public void addAssignmentOption() {
614: try {
615: optionWrapper.addOption(optionWrapper
616: .getAssignmentOptions(), assignmentOptionKey,
617: assignmentOptionValue, false);
618: assignmentOptionKey = null;
619: assignmentOptionValue = null;
620: } catch (Throwable t) {
621: new FxFacesMsgErr(t).addToContext();
622: }
623: }
624:
625: public void addGroupOption() {
626: try {
627: optionWrapper.addOption(
628: optionWrapper.getStructureOptions(),
629: groupOptionKey, groupOptionValue,
630: groupOptionOverridable);
631: groupOptionKey = null;
632: groupOptionValue = null;
633: groupOptionOverridable = true;
634: } catch (Throwable t) {
635: new FxFacesMsgErr(t).addToContext();
636: }
637: }
638:
639: public void deleteAssignmentOption() {
640: optionWrapper.deleteOption(
641: optionWrapper.getAssignmentOptions(), optionFiler);
642: }
643:
644: public void deleteGroupOption() {
645: optionWrapper.deleteOption(optionWrapper.getStructureOptions(),
646: optionFiler);
647: }
648:
649: /**
650: * Hack in order to use command buttons to submit the form values
651: * and update the view of GUI elements
652: */
653: public void doNothing() {
654: }
655:
656: /**
657: * Returns all pgroup assignments that are referencing this property which the
658: * current user may see, excluding the system internal assignments.
659: *
660: * @return a list of group assignments that are referencing this group.
661: */
662: public List<FxGroupAssignment> getReferencingGroupAssignments() {
663: List<FxGroupAssignment> assignments = CacheAdmin
664: .getFilteredEnvironment().getGroupAssignments(true);
665: List<FxGroupAssignment> result = new ArrayList<FxGroupAssignment>();
666: for (FxGroupAssignment assignment : assignments) {
667: if (assignment.getGroup().getId() == group.getId()
668: && !assignment.isSystemInternal()) {
669: result.add(assignment);
670: }
671: }
672: return result;
673: }
674: }
|