1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.ken.util;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.log4j.Logger;
20 import org.kuali.rice.core.api.config.property.ConfigContext;
21 import org.kuali.rice.core.api.criteria.Predicate;
22 import org.kuali.rice.core.api.criteria.QueryByCriteria;
23 import org.kuali.rice.core.framework.persistence.dao.GenericDao;
24 import org.kuali.rice.ken.bo.NotificationBo;
25 import org.kuali.rice.ken.bo.NotificationChannelBo;
26 import org.kuali.rice.ken.bo.NotificationContentTypeBo;
27 import org.kuali.rice.ken.bo.NotificationPriorityBo;
28 import org.kuali.rice.ken.bo.NotificationProducerBo;
29 import org.kuali.rice.ken.bo.NotificationRecipientBo;
30 import org.kuali.rice.ken.bo.NotificationSenderBo;
31 import org.kuali.rice.ken.service.NotificationContentTypeService;
32 import org.kuali.rice.krad.data.DataObjectService;
33 import org.w3c.dom.Document;
34 import org.w3c.dom.Element;
35 import org.w3c.dom.Node;
36 import org.w3c.dom.NodeList;
37 import org.xml.sax.EntityResolver;
38 import org.xml.sax.ErrorHandler;
39 import org.xml.sax.InputSource;
40 import org.xml.sax.SAXException;
41 import org.xml.sax.SAXParseException;
42
43 import javax.xml.namespace.NamespaceContext;
44 import javax.xml.parsers.DocumentBuilder;
45 import javax.xml.parsers.DocumentBuilderFactory;
46 import javax.xml.parsers.ParserConfigurationException;
47 import javax.xml.transform.stream.StreamSource;
48 import java.io.IOException;
49 import java.sql.Timestamp;
50 import java.text.DateFormat;
51 import java.text.ParseException;
52 import java.text.SimpleDateFormat;
53 import java.util.ArrayList;
54 import java.util.Collections;
55 import java.util.Date;
56 import java.util.HashMap;
57 import java.util.List;
58 import java.util.Map;
59 import java.util.TimeZone;
60
61 import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
62
63
64
65
66
67 public final class Util {
68 private static final Logger LOG = Logger.getLogger(Util.class);
69
70 public static final java.lang.String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
71 public static final java.lang.String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
72
73 public static final NamespaceContext NOTIFICATION_NAMESPACE_CONTEXT
74 = new ConfiguredNamespaceContext(Collections.singletonMap("nreq", "ns:notification/NotificationRequest"));
75
76 private static final String ZULU_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
77 private static final TimeZone ZULU_TZ = TimeZone.getTimeZone("UTC");
78
79 private static final String CURR_TZ_FORMAT = "MM/dd/yyyy hh:mm a";
80
81 private Util() {
82 throw new UnsupportedOperationException("do not call");
83 }
84
85
86
87
88 public static String getNotificationSystemUser() {
89 String system_user = ConfigContext.getCurrentContextConfig().getProperty(NotificationConstants.KEW_CONSTANTS.NOTIFICATION_SYSTEM_USER_PARAM);
90 if (system_user == null) {
91 system_user = NotificationConstants.KEW_CONSTANTS.NOTIFICATION_SYSTEM_USER;
92 }
93 return system_user;
94 }
95
96
97
98
99
100
101
102
103 public static Date parseXSDDateTime(String dateTimeString) throws ParseException {
104 return createZulu().parse(dateTimeString);
105 }
106
107
108
109
110
111
112 public static String toXSDDateTimeString(Date d) {
113 return createZulu().format(d);
114 }
115
116
117
118
119
120 public static String getCurrentDateTime() {
121 return toUIDateTimeString(new Date());
122 }
123
124
125
126
127
128 public static String toUIDateTimeString(Date d) {
129 return createCurrTz().format(d);
130 }
131
132
133
134
135
136 public static Date parseUIDateTime(String s) throws ParseException {
137 return createCurrTz().parse(s);
138 }
139
140
141
142
143
144
145
146 public static NamespaceContext getNotificationNamespaceContext(Document doc) {
147 return new CompoundNamespaceContext(NOTIFICATION_NAMESPACE_CONTEXT, new DocumentNamespaceContext(doc));
148 }
149
150
151
152
153
154
155 public static EntityResolver getNotificationEntityResolver(NotificationContentTypeService notificationContentTypeService) {
156 return new CompoundEntityResolver(new ClassLoaderEntityResolver("schema", "notification"),
157 new ContentTypeEntityResolver(notificationContentTypeService));
158 }
159
160
161
162
163
164
165
166 public static String transformContent(NotificationBo notification) {
167 NotificationContentTypeBo contentType = notification.getContentType();
168 String xsl = contentType.getXsl();
169
170 LOG.debug("xsl: "+xsl);
171
172 XslSourceResolver xslresolver = new XslSourceResolver();
173
174 StreamSource xslsource = xslresolver.resolveXslFromString(xsl);
175 String content = notification.getContent();
176 LOG.debug("xslsource:"+xslsource.toString());
177
178 String contenthtml = new String();
179 try {
180 ContentTransformer transformer = new ContentTransformer(xslsource);
181 contenthtml = transformer.transform(content);
182 LOG.debug("html: "+contenthtml);
183 } catch (IOException ex) {
184 LOG.error("IOException transforming document",ex);
185 } catch (Exception ex) {
186 LOG.error("Exception transforming document",ex);
187 }
188 return contenthtml;
189 }
190
191
192
193
194
195
196
197
198
199
200
201 public static Document parse(final InputSource source, boolean validate, boolean namespaceAware, EntityResolver entityResolver) throws ParserConfigurationException, IOException, SAXException {
202
203 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
204 dbf.setValidating(validate);
205 dbf.setNamespaceAware(namespaceAware);
206 dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
207 DocumentBuilder db = dbf.newDocumentBuilder();
208 if (entityResolver != null) {
209 db.setEntityResolver(entityResolver);
210 }
211 db.setErrorHandler(new ErrorHandler() {
212 public void warning(SAXParseException se) {
213 LOG.warn("Warning parsing xml doc " + source, se);
214 }
215 public void error(SAXParseException se) throws SAXException {
216 LOG.error("Error parsing xml doc " + source, se);
217 throw se;
218 }
219 public void fatalError(SAXParseException se) throws SAXException {
220 LOG.error("Fatal error parsing xml doc " + source, se);
221 throw se;
222 }
223 });
224 return db.parse(source);
225 }
226
227
228
229
230
231
232
233
234
235
236
237
238 public static Document parseWithNotificationEntityResolver(final InputSource source, boolean validate, boolean namespaceAware, NotificationContentTypeService notificationContentTypeService) throws ParserConfigurationException, IOException, SAXException {
239 return parse(source, validate, namespaceAware, getNotificationEntityResolver(notificationContentTypeService));
240 }
241
242
243
244
245
246
247
248
249 public static Element getChildElement(Node parent, String name) {
250 NodeList childList = parent.getChildNodes();
251 for (int i = 0; i < childList.getLength(); i++) {
252 Node node = childList.item(i);
253
254
255
256
257
258 if (node.getNodeType() == Node.ELEMENT_NODE
259 && (name.equals(node.getLocalName())
260 || name.equals(node.getNodeName()))) {
261 return (Element) node;
262 }
263 }
264 return null;
265 }
266
267
268
269
270
271
272
273 public static final NotificationBo cloneNotificationWithoutObjectReferences(NotificationBo notification) {
274 NotificationBo clone = new NotificationBo();
275
276
277 if(notification.getCreationDateTime() != null) {
278 clone.setCreationDateTimeValue(new Timestamp(notification.getCreationDateTimeValue().getTime()));
279 }
280 if(notification.getAutoRemoveDateTime() != null) {
281 clone.setAutoRemoveDateTimeValue(new Timestamp(notification.getAutoRemoveDateTimeValue().getTime()));
282 }
283 clone.setContent(new String(notification.getContent()));
284 clone.setDeliveryType(new String(notification.getDeliveryType()));
285 if(notification.getId() != null) {
286 clone.setId(new Long(notification.getId()));
287 }
288 clone.setProcessingFlag(new String(notification.getProcessingFlag()));
289 if(notification.getSendDateTimeValue() != null) {
290 clone.setSendDateTimeValue(new Timestamp(notification.getSendDateTimeValue().getTime()));
291 }
292
293 clone.setTitle(notification.getTitle());
294
295
296 NotificationChannelBo channel = new NotificationChannelBo();
297 channel.setId(new Long(notification.getChannel().getId()));
298 channel.setName(new String(notification.getChannel().getName()));
299 channel.setDescription(new String(notification.getChannel().getDescription()));
300 channel.setSubscribable(new Boolean(notification.getChannel().isSubscribable()).booleanValue());
301 clone.setChannel(channel);
302
303
304 NotificationContentTypeBo contentType = new NotificationContentTypeBo();
305 contentType.setId(new Long(notification.getContentType().getId()));
306 contentType.setDescription(new String(notification.getContentType().getDescription()));
307 contentType.setName(new String(notification.getContentType().getName()));
308 contentType.setNamespace(new String(notification.getContentType().getNamespace()));
309 clone.setContentType(contentType);
310
311
312 NotificationPriorityBo priority = new NotificationPriorityBo();
313 priority.setDescription(new String(notification.getPriority().getDescription()));
314 priority.setId(new Long(notification.getPriority().getId()));
315 priority.setName(new String(notification.getPriority().getName()));
316 priority.setOrder(new Integer(notification.getPriority().getOrder()));
317 clone.setPriority(priority);
318
319
320 NotificationProducerBo producer = new NotificationProducerBo();
321 producer.setDescription(new String(notification.getProducer().getDescription()));
322 producer.setId(new Long(notification.getProducer().getId()));
323 producer.setName(new String(notification.getProducer().getName()));
324 producer.setContactInfo(new String(notification.getProducer().getContactInfo()));
325 clone.setProducer(producer);
326
327
328 ArrayList<NotificationRecipientBo> recipients = new ArrayList<NotificationRecipientBo>();
329 for(int i = 0; i < notification.getRecipients().size(); i++) {
330 NotificationRecipientBo recipient = notification.getRecipient(i);
331 NotificationRecipientBo cloneRecipient = new NotificationRecipientBo();
332 cloneRecipient.setRecipientId(new String(recipient.getRecipientId()));
333 cloneRecipient.setRecipientType(new String(recipient.getRecipientType()));
334
335 recipients.add(cloneRecipient);
336 }
337 clone.setRecipients(recipients);
338
339
340 ArrayList<NotificationSenderBo> senders = new ArrayList<NotificationSenderBo>();
341 for(int i = 0; i < notification.getSenders().size(); i++) {
342 NotificationSenderBo sender = notification.getSender(i);
343 NotificationSenderBo cloneSender = new NotificationSenderBo();
344 cloneSender.setSenderName(new String(sender.getSenderName()));
345
346 senders.add(cloneSender);
347 }
348 clone.setSenders(senders);
349
350 return clone;
351 }
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366 public static <T> T retrieveFieldReference(String fieldName, String keyName, String keyValue, Class clazz,
367 DataObjectService dataObjectService, Boolean searchCurrentField) throws RuntimeException {
368
369 LOG.debug(fieldName + " key value: " + keyValue);
370 if (StringUtils.isBlank(keyValue)) {
371 throw new IllegalArgumentException(fieldName + " must be specified in notification");
372 }
373
374 List<Predicate> predicates = new ArrayList<Predicate>();
375 predicates.add(equal(keyName, keyValue));
376 if (searchCurrentField) {
377 predicates.add(equal("current", Boolean.TRUE));
378 }
379 QueryByCriteria.Builder criteria = QueryByCriteria.Builder.create();
380 criteria.setPredicates(predicates.toArray(new Predicate[predicates.size()]));
381 List<T> references = dataObjectService.findMatching(clazz, criteria.build()).getResults();
382
383 if (references.isEmpty()) {
384 throw new IllegalArgumentException(fieldName + " '" + keyValue + "' not found");
385 }
386 if (references.size() > 1) {
387 throw new RuntimeException("More than one item found for the given value: " + keyValue);
388 }
389
390 return references.get(0);
391 }
392
393 public static <T> T retrieveFieldReference(String fieldName, String keyName, String keyValue, Class clazz, DataObjectService dataObjectService) throws RuntimeException {
394 return retrieveFieldReference(fieldName, keyName, keyValue, clazz, dataObjectService, false);
395 }
396
397 private static DateFormat createZulu() {
398 final DateFormat df = new SimpleDateFormat(ZULU_FORMAT);
399 df.setTimeZone(ZULU_TZ);
400 return df;
401 }
402
403
404 private static DateFormat createCurrTz() {
405 return new SimpleDateFormat(CURR_TZ_FORMAT);
406 }
407 }