KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > emailnotifier > serverimpl > EmailNotifierImpl


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.outerj.daisy.emailnotifier.serverimpl;
17
18 import org.apache.avalon.framework.logger.AbstractLogEnabled;
19 import org.apache.avalon.framework.service.Serviceable;
20 import org.apache.avalon.framework.service.ServiceManager;
21 import org.apache.avalon.framework.service.ServiceException;
22 import org.apache.avalon.framework.activity.Initializable;
23 import org.apache.avalon.framework.configuration.Configurable;
24 import org.apache.avalon.framework.configuration.Configuration;
25 import org.apache.avalon.framework.configuration.ConfigurationException;
26 import org.apache.xmlbeans.XmlObject;
27 import org.apache.xmlbeans.XmlException;
28 import org.apache.commons.lang.StringUtils;
29 import org.outerj.daisy.emailer.Emailer;
30 import org.outerj.daisy.jms.JmsClient;
31 import org.outerj.daisy.repository.*;
32 import org.outerj.daisy.repository.acl.AclResultInfo;
33 import org.outerj.daisy.repository.user.UserManager;
34 import org.outerj.daisy.repository.user.User;
35 import org.outerj.daisy.repository.user.UserNotFoundException;
36 import org.outerj.daisy.repository.user.Role;
37 import org.outerj.daisy.emailnotifier.EmailSubscriptionManager;
38 import org.outerj.daisy.emailnotifier.Subscriber;
39 import org.outerj.daisy.emailnotifier.serverimpl.formatters.*;
40 import org.outerx.daisy.x10.*;
41
42 import javax.jms.MessageListener JavaDoc;
43 import javax.jms.Message JavaDoc;
44 import javax.jms.TextMessage JavaDoc;
45 import java.util.Map JavaDoc;
46 import java.util.HashMap JavaDoc;
47 import java.util.Locale JavaDoc;
48 import java.util.ArrayList JavaDoc;
49 import java.lang.reflect.Method JavaDoc;
50
51 /**
52  * @avalon.component version="1.0" name="emailnotifier" lifestyle="singleton"
53  */

54 public class EmailNotifierImpl extends AbstractLogEnabled implements Serviceable, Initializable, Configurable {
55     private ServiceManager serviceManager;
56     private Repository repository;
57     private String JavaDoc repoUser;
58     private String JavaDoc repoPassword;
59     private Emailer emailer;
60     private JmsClient jmsClient;
61     private String JavaDoc jmsTopicName;
62     private String JavaDoc subscriptionName;
63     private EventListener eventListener = new EventListener();
64     private String JavaDoc subjectPrefix;
65     private Map JavaDoc mailTemplateFactories;
66     private DocumentURLProviderImpl documentURLProvider = new DocumentURLProviderImpl();
67
68     /**
69      * @avalon.dependency key="jmsclient" type="org.outerj.daisy.jms.JmsClient"
70      * @avalon.dependency key="repository-manager" type="org.outerj.daisy.repository.RepositoryManager"
71      */

72     public void service(ServiceManager serviceManager) throws ServiceException {
73         this.jmsClient = (JmsClient)serviceManager.lookup("jmsclient");
74         this.serviceManager = serviceManager;
75     }
76
77     public void configure(Configuration configuration) throws ConfigurationException {
78         this.jmsTopicName = configuration.getChild("jmsTopic").getValue();
79         this.subscriptionName = configuration.getChild("jmsSubscriptionName").getValue();
80
81         Configuration repositoryUserConf = configuration.getChild("repositoryUser", false);
82         if (repositoryUserConf == null)
83             throw new ConfigurationException("Missing repositoryUser configuration element.");
84
85         repoUser = repositoryUserConf.getAttribute("user");
86         repoPassword = repositoryUserConf.getAttribute("password");
87
88         subjectPrefix = configuration.getChild("emailSubjectPrefix").getValue("");
89         if (subjectPrefix.length() > 0)
90             subjectPrefix += " ";
91
92         Configuration[] documentURLs = configuration.getChild("documentURLs").getChildren("documentURL");
93         for (int i = 0; i < documentURLs.length; i++) {
94             String JavaDoc collection = documentURLs[i].getAttribute("collection", null);
95             String JavaDoc branch = documentURLs[i].getAttribute("branch", null);
96             String JavaDoc language = documentURLs[i].getAttribute("language", null);
97             String JavaDoc url = documentURLs[i].getAttribute("url");
98             documentURLProvider.addRule(collection, branch, language, url);
99         }
100     }
101
102     public void initialize() throws Exception JavaDoc {
103         jmsClient.registerDurableTopicListener(jmsTopicName, subscriptionName, eventListener);
104
105         RepositoryManager repositoryManager = (RepositoryManager)serviceManager.lookup("repository-manager");
106         try {
107             repository = repositoryManager.getRepository(new Credentials(repoUser, repoPassword));
108         } catch (Throwable JavaDoc e) {
109             throw new Exception JavaDoc("Problem getting repository.", e);
110         } finally {
111             serviceManager.release(repositoryManager);
112         }
113
114         this.emailer = (Emailer)repository.getExtension("Emailer");
115
116         mailTemplateFactories = new HashMap JavaDoc();
117         mailTemplateFactories.put("DocumentVariantCreated", new DocumentVariantCreatedTemplateFactory());
118         mailTemplateFactories.put("DocumentVariantUpdated", new DocumentVariantUpdatedTemplateFactory());
119         mailTemplateFactories.put("DocumentVariantDeleted", new DocumentVariantDeletedTemplateFactory());
120         //mailTemplateFactories.put("DocumentUpdated", new DocumentUpdatedTemplateFactory());
121
mailTemplateFactories.put("VersionStateChanged", new VersionStateChangedTemplateFactory());
122         mailTemplateFactories.put("CommentCreated", new CommentCreatedTemplateFactory());
123         mailTemplateFactories.put("CommentDeleted", new CommentDeletedTemplateFactory());
124     }
125
126     class EventListener implements MessageListener JavaDoc {
127         public void onMessage(Message JavaDoc aMessage) {
128             try {
129                 TextMessage JavaDoc message = (TextMessage JavaDoc)aMessage;
130                 String JavaDoc eventType = message.getStringProperty("type");
131
132                 if (eventType == null) {
133                     getLogger().error("Missing type property on JMS message.");
134                     return;
135                 }
136
137                 XmlObject eventDescription = parseEventDescription(message.getText(), eventType);
138                 if (eventDescription == null) {
139                     return;
140                 }
141
142                 EmailSubscriptionManager subscriptionManager = (EmailSubscriptionManager)repository.getExtension("EmailSubscriptionManager");
143
144                 try {
145                     // In case it is a document related event, retrieve the document ID to which it applies
146
long documentId = -1;
147                     long branchId = -1;
148                     long languageId = -1;
149                     long[] collectionIds = null;
150                     String JavaDoc commentVisibility = null;
151                     if (eventType.startsWith("Document")) {
152                         DocumentDocument.Document documentXml = null;
153                         if (eventType.equals("DocumentVariantCreated")) {
154                             documentXml = ((DocumentVariantCreatedDocument)eventDescription).getDocumentVariantCreated().getNewDocumentVariant().getDocument();
155                         } else if (eventType.equals("DocumentVariantUpdated")) {
156                             documentXml = ((DocumentVariantUpdatedDocument)eventDescription).getDocumentVariantUpdated().getNewDocumentVariant().getDocument();
157                         } else if (eventType.equals("DocumentVariantDeleted")) {
158                             documentXml = ((DocumentVariantDeletedDocument)eventDescription).getDocumentVariantDeleted().getDeletedDocumentVariant().getDocument();
159                             collectionIds = documentXml.getCollectionIds().getCollectionIdArray();
160                         }/* else if (eventType.equals("DocumentUpdated")) {
161                             documentXml = ((DocumentUpdatedDocument)eventDescription).getDocumentUpdated().getNewDocument().getDocument();
162                         } */

163
164                         if (documentXml != null) {
165                             documentId = documentXml.getId();
166                             branchId = documentXml.getBranchId();
167                             languageId = documentXml.getLanguageId();
168                         }
169                     } else if (eventType.equals("VersionStateChanged")) {
170                         VersionStateChangedDocument.VersionStateChanged versionStateChangedXml = ((VersionStateChangedDocument)eventDescription).getVersionStateChanged();
171                         documentId = versionStateChangedXml.getDocumentId();
172                         branchId = versionStateChangedXml.getBranchId();
173                         languageId = versionStateChangedXml.getLanguageId();
174                     } else if (eventType.equals("CommentCreated")) {
175                         CommentDocument.Comment commentXml = ((CommentCreatedDocument)eventDescription).getCommentCreated().getNewComment().getComment();
176                         documentId = commentXml.getDocumentId();
177                         branchId = commentXml.getBranchId();
178                         languageId = commentXml.getLanguageId();
179                         commentVisibility = commentXml.getVisibility().toString();
180                     } else if (eventType.equals("CommentDeleted")) {
181                         CommentDocument.Comment commentXml = ((CommentDeletedDocument)eventDescription).getCommentDeleted().getDeletedComment().getComment();
182                         documentId = commentXml.getDocumentId();
183                         branchId = commentXml.getBranchId();
184                         languageId = commentXml.getLanguageId();
185                         commentVisibility = commentXml.getVisibility().toString();
186                     }
187
188                     if (documentId != -1 && collectionIds == null) {
189                         try {
190                             DocumentCollection[] documentCollections = repository.getDocument(documentId, branchId, languageId, false).getCollections().getArray();
191                             collectionIds = new long[documentCollections.length];
192                             for (int i = 0; i < documentCollections.length; i++)
193                                 collectionIds[i] = documentCollections[i].getId();
194                         } catch (DocumentNotFoundException e) {
195                             // document has been deleted since we got this event, skip it (the event)
196
return;
197                         } catch (DocumentVariantNotFoundException e) {
198                             // document variant has been deleted since we got this event, skip it (the event)
199
return;
200                         }
201                     }
202
203                     Subscriber[] subscribers;
204                     if (eventType.equals("DocumentVariantCreated") || eventType.equals("DocumentVariantDeleted") || eventType.equals("DocumentVariantUpdated") || eventType.equals("DocumentUpdated") || eventType.equals("VersionStateChanged")) {
205                         subscribers = subscriptionManager.getAllDocumentEventSubscribers(documentId, branchId, languageId, collectionIds).getArray();
206                     } else if (eventType.startsWith("FieldType") || eventType.startsWith("PartType") || eventType.startsWith("DocumentType")) {
207                         subscribers = subscriptionManager.getAllSchemaEventSubscribers().getArray();
208                     } else if (eventType.startsWith("User") || eventType.startsWith("Role")) {
209                         subscribers = subscriptionManager.getAllUserEventSubscribers().getArray();
210                     } else if (eventType.startsWith("Collection")) {
211                         subscribers = subscriptionManager.getAllCollectionEventSubscribers().getArray();
212                     } else if (eventType.startsWith("Acl")) {
213                         subscribers = subscriptionManager.getAllAclEventSubscribers().getArray();
214                     } else if (eventType.startsWith("Comment")) {
215                         subscribers = subscriptionManager.getAllCommentEventSubscribers(documentId, branchId, languageId, collectionIds).getArray();
216                     } else {
217                         if (getLogger().isDebugEnabled())
218                             getLogger().debug("Unrecognized event type: " + eventType);
219                         return;
220                     }
221
222                     if (subscribers.length > 0) {
223                         UserManager userManager = repository.getUserManager();
224
225                         MailTemplate mailTemplate = null;
226
227                         for (int i = 0; i < subscribers.length; i++) {
228                             long userId = subscribers[i].getUserId();
229                             User user = null;
230                             try {
231                                 user = userManager.getUser(userId, false);
232                             } catch (UserNotFoundException e) {
233                                 // user does not exist anymore, cleanup his subscription
234
subscriptionManager.deleteSubscription(userId);
235                                 continue;
236                             }
237
238                             String JavaDoc email = user.getEmail();
239                             if (email == null || email.equals("")) {
240                                 getLogger().warn("User " + user.getId() + " (" + user.getDisplayName() + ") is subscribed for email notifications but doens't have an email address configured.");
241                                 continue;
242                             }
243
244                             if ((eventType.startsWith("User") || eventType.startsWith("Role")) && !user.hasRole(Role.ADMINISTRATOR)) {
245                                 continue;
246                             }
247
248                             // If a document is deleted, it is impossible to check the access rights for the document
249
// (well, it might be possible by creating a dummy document object based on the XML document
250
// description embedded in the JMS event, but ignore this for now), therefore we only
251
// send document deletion events to administrators.
252
if (eventType.equals("DocumentVariantDeleted") && !user.hasRole(Role.ADMINISTRATOR)) {
253                                 continue;
254                             }
255
256                             // If it is a document-related event, check ACL
257
boolean isReadAllowed = false;
258                             boolean isWriteAllowed = false;
259                             if (documentId != -1 && !eventType.equals("DocumentVariantDeleted")) {
260                                 try {
261                                     // check if the user has a role which allows him/her to access this document
262
long[] roles = user.getAllRoleIds();
263                                     AclResultInfo aclResultInfo = repository.getAccessManager().getAclInfoOnLive(userId, roles, documentId, branchId, languageId);
264                                     if (aclResultInfo.isAllowed(org.outerj.daisy.repository.acl.AclPermission.WRITE)) {
265                                         isReadAllowed = true;
266                                         isWriteAllowed = true;
267                                     }
268                                     if (aclResultInfo.isAllowed(org.outerj.daisy.repository.acl.AclPermission.READ)) {
269                                         isReadAllowed = true;
270                                     }
271                                 } catch (DocumentNotFoundException e) {
272                                     // the document has been deleted since this event occured, ignore it
273
continue;
274                                 } catch (DocumentVariantNotFoundException e) {
275                                     // the document variant has been deleted since this event occured, ignore it
276
continue;
277                                 }
278                                 if (!isReadAllowed)
279                                     continue; // skip this event for this user
280
}
281
282                             if (eventType.startsWith("Comment")) {
283                                 if (commentVisibility.equals("private")) {
284                                     // don't send mail for private comments
285
continue;
286                                 }
287                                 if (commentVisibility.equals("editors") && !isWriteAllowed) {
288                                     continue;
289                                 }
290                             }
291
292                             if (mailTemplate == null)
293                                 mailTemplate = getMailTemplate(eventType, eventDescription);
294
295                             Locale JavaDoc locale = subscribers[i].getLocale();
296                             if (locale == null)
297                                 locale = Locale.US;
298                             emailer.send(email, subjectPrefix + mailTemplate.getSubject(locale), mailTemplate.getMessage(locale));
299                         }
300                     }
301                 } finally {
302                     cleanupSubscriptions(eventType, eventDescription, subscriptionManager);
303                 }
304             } catch (Throwable JavaDoc e) {
305                 getLogger().error("Error processing JMS event.", e);
306             }
307         }
308     }
309
310     private void cleanupSubscriptions(String JavaDoc eventType, XmlObject eventDescription, EmailSubscriptionManager subscriptionManager) {
311         try {
312             if (eventType.equals("DocumentDeleted")) {
313                 DocumentDocument.Document documentXml = ((DocumentDeletedDocument)eventDescription).getDocumentDeleted().getDeletedDocument().getDocument();
314                 subscriptionManager.deleteAllSubscriptionsForDocument(documentXml.getId());
315             } if (eventType.equals("DocumentVariantDeleted")) {
316                 DocumentDocument.Document documentXml = ((DocumentVariantDeletedDocument)eventDescription).getDocumentVariantDeleted().getDeletedDocumentVariant().getDocument();
317                 VariantKey variantKey = new VariantKey(documentXml.getId(), documentXml.getBranchId(), documentXml.getLanguageId());
318                 subscriptionManager.deleteAllSubscriptionsForDocumentVariant(variantKey);
319             } else if (eventType.equals("CollectionDeleted")) {
320                 CollectionDeletedDocument collectionDeletedDocument = (CollectionDeletedDocument)eventDescription;
321                 long id = collectionDeletedDocument.getCollectionDeleted().getDeletedCollection().getCollection().getId();
322                 subscriptionManager.deleteAllSubscriptionsForCollection(id);
323             }
324         } catch (Throwable JavaDoc e) {
325             getLogger().error("Error in subscription cleanup handling.", e);
326         }
327     }
328
329     interface EventParser {
330         XmlObject parse(String JavaDoc data) throws XmlException;
331     }
332
333     private static final Map JavaDoc EVENT_PARSERS = new HashMap JavaDoc();
334     static {
335         try {
336             //EVENT_PARSERS.put("DocumentUpdated", DocumentUpdatedDocument.Factory.class.getMethod("parse", new Class[] { String.class }));
337
EVENT_PARSERS.put("DocumentDeleted", DocumentDeletedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
338             EVENT_PARSERS.put("DocumentVariantCreated", DocumentVariantCreatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
339             EVENT_PARSERS.put("DocumentVariantUpdated", DocumentVariantUpdatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
340             EVENT_PARSERS.put("DocumentVariantDeleted", DocumentVariantDeletedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
341             EVENT_PARSERS.put("FieldTypeCreated", FieldTypeCreatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
342             EVENT_PARSERS.put("FieldTypeUpdated", FieldTypeUpdatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
343             EVENT_PARSERS.put("FieldTypeDeleted", FieldTypeDeletedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
344             EVENT_PARSERS.put("PartTypeCreated", PartTypeCreatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
345             EVENT_PARSERS.put("PartTypeUpdated", PartTypeUpdatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
346             EVENT_PARSERS.put("PartTypeDeleted", PartTypeDeletedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
347             EVENT_PARSERS.put("DocumentTypeCreated", DocumentTypeCreatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
348             EVENT_PARSERS.put("DocumentTypeUpdated", DocumentTypeUpdatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
349             EVENT_PARSERS.put("DocumentTypeDeleted", DocumentTypeDeletedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
350             EVENT_PARSERS.put("UserCreated", UserCreatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
351             EVENT_PARSERS.put("UserUpdated", UserUpdatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
352             EVENT_PARSERS.put("UserDeleted", UserDeletedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
353             EVENT_PARSERS.put("RoleCreated", RoleCreatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
354             EVENT_PARSERS.put("RoleUpdated", RoleUpdatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
355             EVENT_PARSERS.put("RoleDeleted", RoleDeletedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
356             EVENT_PARSERS.put("CollectionCreated", CollectionCreatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
357             EVENT_PARSERS.put("CollectionUpdated", CollectionUpdatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
358             EVENT_PARSERS.put("CollectionDeleted", CollectionDeletedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
359             EVENT_PARSERS.put("AclUpdated", AclUpdatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
360             EVENT_PARSERS.put("CommentCreated", CommentCreatedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
361             EVENT_PARSERS.put("CommentDeleted", CommentDeletedDocument.Factory.class.getMethod("parse", new Class JavaDoc[] { String JavaDoc.class }));
362         } catch (Exception JavaDoc e) {
363             throw new RuntimeException JavaDoc("Error initializing event parsers map.", e);
364         }
365     }
366
367
368     private XmlObject parseEventDescription(String JavaDoc data, String JavaDoc eventType) {
369         try {
370             Method JavaDoc parseMethod = (Method JavaDoc)EVENT_PARSERS.get(eventType);
371             if (parseMethod != null) {
372                 return (XmlObject)parseMethod.invoke(null, new Object JavaDoc[] {data});
373             }
374         } catch (Exception JavaDoc e) {
375             getLogger().error("Error parsing event description XML.", e);
376         }
377         return null;
378     }
379
380     private MailTemplate getMailTemplate(String JavaDoc eventType, XmlObject eventDescription) throws Exception JavaDoc {
381         MailTemplateFactory factory = (MailTemplateFactory)mailTemplateFactories.get(eventType);
382         if (factory != null) {
383             return factory.createMailTemplate(eventDescription, repository, documentURLProvider);
384         } else {
385             return new DummyMailTemplate(eventType, eventDescription);
386         }
387     }
388
389     class DocumentURLProviderImpl implements DocumentURLProvider {
390         private ArrayList JavaDoc documentURLRules = new ArrayList JavaDoc();
391
392         public String JavaDoc getURL(Document document) {
393             String JavaDoc branch = null;
394             String JavaDoc language = null;
395             try {
396                 branch = repository.getVariantManager().getBranch(document.getBranchId(), false).getName();
397                 language = repository.getVariantManager().getLanguage(document.getLanguageId(), false).getName();
398             } catch (RepositoryException e) {
399                 // rather exceptional exception, just keep going
400
return null;
401             }
402             for (int i = 0; i < documentURLRules.size(); i++) {
403                 DocumentURLRule rule = (DocumentURLRule)documentURLRules.get(i);
404                 boolean variantMatch = (rule.branch == null || branch.equals(rule.branch))
405                         && (rule.language == null || language.equals(rule.language));
406                 if (variantMatch) {
407                     if (rule.collection == null) {
408                         return rule.getURL(document.getId(), document.getBranchId(), document.getLanguageId());
409                     } else {
410                         DocumentCollection[] collections = document.getCollections().getArray();
411                         for (int k = 0; k < collections.length; k++) {
412                             if (collections[k].getName().equals(rule.collection)) {
413                                 return rule.getURL(document.getId(), document.getBranchId(), document.getLanguageId());
414                             }
415                         }
416                     }
417                 }
418             }
419             return null;
420         }
421
422         public void addRule(String JavaDoc collection, String JavaDoc branch, String JavaDoc language, String JavaDoc URL) {
423             DocumentURLRule rule = new DocumentURLRule();
424             rule.collection = collection;
425             rule.branch = branch;
426             rule.language = language;
427             rule.URL = URL;
428             documentURLRules.add(rule);
429         }
430
431         class DocumentURLRule {
432             public String JavaDoc collection;
433             public String JavaDoc branch;
434             public String JavaDoc language;
435             public String JavaDoc URL;
436
437             public String JavaDoc getURL(long documentId, long branchId, long languageId) {
438                 String JavaDoc result = StringUtils.replace(URL, "{id}", String.valueOf(documentId));
439                 result = StringUtils.replace(result, "{branch}", String.valueOf(branchId));
440                 result = StringUtils.replace(result, "{language}", String.valueOf(languageId));
441                 return result;
442             }
443         }
444     }
445
446 }
Popular Tags