001: package org.tigris.scarab.actions;
002:
003: import java.util.Collections;
004: import java.util.Iterator;
005: import java.util.List;
006: import java.util.Map;
007: import java.util.StringTokenizer;
008:
009: import org.apache.torque.TorqueException;
010: import org.apache.torque.om.NumberKey;
011: import org.apache.torque.om.ObjectKey;
012: import org.apache.torque.util.Criteria;
013: import org.apache.turbine.RunData;
014: import org.apache.turbine.TemplateContext;
015: import org.apache.turbine.tool.IntakeTool;
016: import org.tigris.scarab.actions.base.RequireLoginFirstAction;
017: import org.tigris.scarab.actions.base.ScarabTemplateAction;
018: import org.tigris.scarab.notification.ActivityType;
019: import org.tigris.scarab.notification.NotificationManagerFactory;
020: import org.tigris.scarab.notification.ScarabNewNotificationManager;
021: import org.tigris.scarab.om.Module;
022: import org.tigris.scarab.om.NotificationFilter;
023: import org.tigris.scarab.om.NotificationFilterManager;
024: import org.tigris.scarab.om.NotificationFilterPeer;
025: import org.tigris.scarab.om.NotificationStatus;
026: import org.tigris.scarab.om.NotificationStatusManager;
027: import org.tigris.scarab.om.NotificationStatusPeer;
028: import org.tigris.scarab.om.Query;
029: import org.tigris.scarab.om.QueryManager;
030: import org.tigris.scarab.om.ScarabUser;
031: import org.tigris.scarab.tools.ScarabGlobalTool;
032: import org.tigris.scarab.tools.ScarabLocalizationTool;
033: import org.tigris.scarab.tools.ScarabRequestTool;
034: import org.tigris.scarab.tools.localization.L10NKeySet;
035: import org.tigris.scarab.util.ScarabConstants;
036:
037: /* ================================================================
038: * Copyright (c) 2005 CollabNet. All rights reserved.
039: *
040: * Redistribution and use in source and binary forms, with or without
041: * modification, are permitted provided that the following conditions are
042: * met:
043: *
044: * 1. Redistributions of source code must retain the above copyright
045: * notice, this list of conditions and the following disclaimer.
046: *
047: * 2. Redistributions in binary form must reproduce the above copyright
048: * notice, this list of conditions and the following disclaimer in the
049: * documentation and/or other materials provided with the distribution.
050: *
051: * 3. The end-user documentation included with the redistribution, if
052: * any, must include the following acknowlegement: "This product includes
053: * software developed by Collab.Net <http://www.Collab.Net/>."
054: * Alternately, this acknowlegement may appear in the software itself, if
055: * and wherever such third-party acknowlegements normally appear.
056: *
057: * 4. The hosted project names must not be used to endorse or promote
058: * products derived from this software without prior written
059: * permission. For written permission, please contact info@collab.net.
060: *
061: * 5. Products derived from this software may not use the "Tigris" or
062: * "Scarab" names nor may "Tigris" or "Scarab" appear in their names without
063: * prior written permission of Collab.Net.
064: *
065: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
066: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
067: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
068: * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
069: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
070: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
071: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
072: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
073: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
074: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
075: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
076: *
077: * ====================================================================
078: *
079: * This software consists of voluntary contributions made by many
080: * individuals on behalf of Collab.Net.
081: */
082:
083: /**
084: * @author hdab
085: *
086: * To change the template for this generated type comment go to
087: * Window - Preferences - Java - Code Generation - Code and Comments
088: */
089: public class ChangeNotificationStatus extends ScarabTemplateAction {
090: /**
091: * Delete notifications from the current user's notification list.
092: * This method is mainly called from the Notification Screen to
093: * remove marked notifications. We assume the request parameters
094: * follow the name convention:
095: *
096: * name="notificationId_${ActivityId}_${CreatorId}_${ReceiverId}"
097: *
098: * with all ${..} variables as integer numbers.
099: * @param data
100: * @param context
101: * @throws Exception
102: */
103: public void doDeletenotifications(RunData data,
104: TemplateContext context) throws Exception {
105: deleteMarkedEntries(data, context);
106: }
107:
108: /**
109: * This is the work horse for the Notification deletion process.
110: * @param data
111: * @param context
112: * @throws Exception
113: */
114: private void deleteMarkedEntries(RunData data,
115: TemplateContext context) throws Exception {
116: Object[] keys = data.getParameters().getKeys();
117: String key;
118: String queryId;
119: ScarabUser user = (ScarabUser) data.getUser();
120:
121: // loop over all notification ids contained in the
122: // current parameter set. These notifications will
123: // be removed from the Notificaiton List now without
124: // rollback!
125: for (int i = 0; i < keys.length; i++) {
126: key = keys[i].toString();
127: if (key.toLowerCase().startsWith("notificationid_")) {
128: Object[] pkeys = extractPrimarykeys(key);
129: Long tid = (Long) pkeys[0];
130: Integer cid = (Integer) pkeys[1];
131: Integer rid = (Integer) pkeys[2];
132: NotificationStatus ns = NotificationStatusPeer
133: .retrieveByPK(tid, cid, rid);
134: ns.markDeleted();
135: }
136: }
137: }
138:
139: /**
140: * Get the primary keys for the object to be deleted.
141: * We assume the following syntax in the given String:
142: *
143: * key="notificationId_${ActivityId}_${CreatorId}_${ReceiverId}"
144: *
145: * The returned array contains three keys in the order:
146: *
147: * ActivityId
148: * CreatorId
149: * ReceiverId
150: *
151: * @param key
152: * @return
153: */
154: private Object[] extractPrimarykeys(String keys) {
155: Object[] keyset = new Object[3];
156: String subkey;
157:
158: StringTokenizer stok = new StringTokenizer(keys, "_");
159: stok.nextToken(); // remove leading "id_"
160: subkey = stok.nextToken(); // this is the TRANSACTION_ID
161: keyset[0] = Long.decode(subkey);
162:
163: subkey = stok.nextToken(); // this is the CREATOR_ID
164: keyset[1] = Integer.decode(subkey);
165:
166: subkey = stok.nextToken(); // this is the RECEIVER_ID
167: keyset[2] = Integer.decode(subkey);
168:
169: return keyset;
170: }
171:
172: // ===============================================================
173: // The following methods are primary for customization issues
174: // ===============================================================
175:
176: public void doCustomize(RunData data, TemplateContext context)
177: throws Exception {
178: customize(data, context);
179: }
180:
181: /**
182: * @param data
183: * @param context
184: * @throws TorqueException
185: */
186: private void customize(RunData data, TemplateContext context)
187: throws Exception {
188: String key;
189: ScarabUser user = (ScarabUser) data.getUser();
190: Integer userId = user.getUserId();
191:
192: ScarabRequestTool scarabR = getScarabRequestTool(context);
193: Module module = scarabR.getCurrentModule();
194: Integer moduleId = module.getModuleId();
195:
196: // The filterMap contains all filters for this user and this module
197: NotificationFilterPeer nfp = new NotificationFilterPeer();
198: Map filterMap = nfp.getCustomization(moduleId, userId);
199:
200: // The list of activityTypes
201: ScarabGlobalTool scarabG = getScarabGlobalTool(context);
202: List activityTypeList = scarabG.getAllNotificationTypeCodes();
203:
204: Iterator iter = activityTypeList.iterator();
205: while (iter.hasNext()) {
206: String code = (String) iter.next();
207: ActivityType activityType = ActivityType
208: .getActivityType(code);
209: boolean theStatus = data.getParameters().getBoolean(
210: code + ":status");
211: boolean theSendSelf = data.getParameters().getBoolean(
212: code + ":self");
213: boolean theSendFailure = data.getParameters().getBoolean(
214: code + ":fail");
215: Integer managerId = NotificationManagerFactory
216: .getInstance().getManagerId();
217:
218: NotificationFilter filter = NotificationFilter
219: .createDefaultFilter(moduleId, userId, managerId,
220: activityType);
221:
222: markUpdateOrNew(filter);
223:
224: // adjust the new attribute values
225: filter.setSendSelf(theSendSelf);
226: filter.setSendFailures(theSendFailure);
227: filter.setFilterState(theStatus);
228:
229: // finally modify in database.
230: modifyInDatabase(filter);
231: }
232: scarabR.setConfirmMessage(L10NKeySet.ChangesSaved);
233: }
234:
235: /**
236: * Check whether the filter needs to be created, updated or removed
237: * and process the particular database call.
238: * from the database.
239: * @param filter
240: * @throws TorqueException
241: * @throws Exception
242: */
243: private void modifyInDatabase(NotificationFilter filter)
244: throws TorqueException, Exception {
245: if (equalsDefaultCustomization(filter)) {
246: if (filter.isNew()) {
247: // don't need to create this filter
248: } else {
249: // can safely remove this filter
250: ObjectKey pk = filter.getPrimaryKey();
251: NotificationFilterPeer.doDelete(pk);
252: }
253: } else {
254: // need to store this filter
255: filter.save();
256: }
257: }
258:
259: /**
260: * Check wether the given filter is allready contained
261: * in the repository and mark it either as new or
262: * already existing.
263: * @param filter
264: * @return
265: */
266: private void markUpdateOrNew(NotificationFilter filter) {
267: // Check if the entry already exists in database:
268: ObjectKey pk = filter.getPrimaryKey();
269: try {
270: if (NotificationFilterManager.getInstance(pk) != null) {
271: filter.setNew(false);
272: }
273: } catch (Exception e) {
274: filter.setNew(true);
275: }
276: }
277:
278: /**
279: * Check equality to default customization.
280: * This filter is equal to the default filter, when it
281: * is equal in all attributes.
282: * Currently the default filter is hard coded, see below
283: * @param filter
284: * @return
285: */
286: private boolean equalsDefaultCustomization(NotificationFilter filter) {
287: // currently we assume, that the filter is
288: // equivalent to the default setting when:
289:
290: if (!filter.getFilterState())
291: return false; // filter enabled
292: if (filter.getSendSelf())
293: return false; // dont send to me
294: if (filter.getSendFailures())
295: return false; // dont send failures
296:
297: // this behaviour will be changed as soon as default settings
298: // are available.
299:
300: return true;
301: }
302:
303: /**
304: * Helper method to retrieve the ScarabRequestTool from the Context
305: */
306: public ScarabGlobalTool getScarabGlobalTool(TemplateContext context) {
307: return (ScarabGlobalTool) context
308: .get(ScarabConstants.SCARAB_GLOBAL_TOOL);
309: }
310:
311: }
|