1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.modules.actions.portlets;
18
19
20 import org.apache.turbine.util.DynamicURI;
21 import org.apache.turbine.util.RunData;
22 import org.apache.turbine.util.StringUtils;
23 import org.apache.turbine.util.security.EntityExistsException;
24 import org.apache.turbine.services.TurbineServices;
25 import org.apache.turbine.services.servlet.TurbineServlet;
26 import org.apache.turbine.services.resources.ResourceService;
27
28
29 import org.apache.velocity.context.Context;
30
31
32 import java.io.File;
33 import java.io.FileWriter;
34 import java.io.FileReader;
35 import java.io.IOException;
36 import java.util.Iterator;
37 import java.util.Vector;
38 import java.util.StringTokenizer;
39
40
41 import org.apache.commons.lang.SerializationUtils;
42 import org.apache.jetspeed.modules.actions.portlets.security.SecurityConstants;
43 import org.apache.jetspeed.om.profile.Profile;
44 import org.apache.jetspeed.om.profile.ProfileLocator;
45 import org.apache.jetspeed.om.profile.QueryLocator;
46 import org.apache.jetspeed.om.profile.PSMLDocument;
47 import org.apache.jetspeed.om.profile.Portlets;
48 import org.apache.jetspeed.portal.portlets.VelocityPortlet;
49 import org.apache.jetspeed.services.Profiler;
50 import org.apache.jetspeed.services.Registry;
51 import org.apache.jetspeed.services.JetspeedSecurity;
52 import org.apache.jetspeed.services.PsmlManager;
53 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
54 import org.apache.jetspeed.services.logging.JetspeedLogger;
55 import org.apache.jetspeed.util.template.JetspeedLink;
56 import org.apache.jetspeed.util.template.JetspeedLinkFactory;
57 import org.apache.jetspeed.services.resources.JetspeedResources;
58 import org.apache.jetspeed.services.psmlmanager.PsmlManagerService;
59 import org.apache.jetspeed.om.profile.BasePSMLDocument;
60 import org.apache.jetspeed.om.security.JetspeedUser;
61 import org.apache.jetspeed.om.security.Role;
62 import org.apache.jetspeed.om.security.Group;
63
64
65 import org.exolab.castor.xml.MarshalException;
66 import org.exolab.castor.xml.Marshaller;
67 import org.exolab.castor.xml.Unmarshaller;
68 import org.exolab.castor.xml.ValidationException;
69 import org.exolab.castor.mapping.Mapping;
70 import org.exolab.castor.mapping.MappingException;
71 import org.xml.sax.InputSource;
72
73
74 import org.apache.xml.serialize.Serializer;
75 import org.apache.xml.serialize.XMLSerializer;
76 import org.apache.xml.serialize.OutputFormat;
77
78 /***
79 * This action enables to update the psml entries
80 *
81 * @author <a href="mailto:david@apache.org">David Sean Taylor</a>
82 * @version $Id: PsmlUpdateAction.java,v 1.18 2004/03/31 04:49:10 morciuch Exp $
83 */
84 public class PsmlUpdateAction extends SecureVelocityPortletAction
85 {
86
87 protected static final String PSML_REFRESH_FLAG = "psmlRefreshFlag";
88 protected static final String TRUE = "true";
89 protected static final String FALSE = "false";
90 protected static final String CATEGORY_NAME = "categoryName";
91 protected static final String CATEGORY_VALUE = "categoryValue";
92 protected static final String COPY_FROM = "copyFrom";
93 protected static final String COPY_TO = "copyTo";
94 protected static final String TEMP_LOCATOR = "tempLocator";
95 protected static final String PSML_UPDATE_PANE = "PsmlForm";
96
97 /***
98 * Static initialization of the logger for this class
99 */
100 private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(PsmlUpdateAction.class.getName());
101
102 /***
103 * Subclasses must override this method to provide default behavior
104 * for the portlet action
105 */
106 /***
107 * Build the normal state content for this portlet.
108 *
109 * @param portlet The velocity-based portlet that is being built.
110 * @param context The velocity context for this request.
111 * @param rundata The turbine rundata context for this request.
112 */
113 protected void buildNormalContext( VelocityPortlet portlet,
114 Context context,
115 RunData rundata )
116 {
117 try
118 {
119
120
121
122 String msgid = rundata.getParameters().getString(SecurityConstants.PARAM_MSGID);
123 if (msgid != null)
124 {
125 int id = Integer.parseInt(msgid);
126 if (id < SecurityConstants.MESSAGES.length)
127 context.put(SecurityConstants.PARAM_MSG, SecurityConstants.MESSAGES[id]);
128
129
130 ProfileLocator locator = (ProfileLocator)rundata.getUser().getTemp(TEMP_LOCATOR);
131 if (locator != null)
132 context.put("profile", Profiler.createProfile(locator));
133 }
134
135 String mode = rundata.getParameters().getString(SecurityConstants.PARAM_MODE);
136 context.put(SecurityConstants.PARAM_MODE, mode);
137 String path = rundata.getParameters().getString(SecurityConstants.PARAM_ENTITY_ID);
138
139 if(mode != null && mode.equals(SecurityConstants.PARAM_MODE_DELETE))
140 {
141 ProfileLocator locator = Profiler.createLocator();
142 locator.createFromPath(path);
143 Profile profile = Profiler.getProfile(locator);
144 if (profile != null)
145 {
146 rundata.getUser().setTemp(TEMP_LOCATOR, locator);
147 context.put("profile", profile);
148 }
149 else
150 logger.error("Profile for Path:"+path+" Not Found!");
151 }
152
153 if(mode != null && mode.equals(SecurityConstants.PARAM_MODE_INSERT))
154 {
155 org.apache.jetspeed.om.registry.Registry mediaTypes = Registry.get(Registry.MEDIA_TYPE);
156 context.put("mediaTypes", mediaTypes.listEntryNames());
157 if (msgid == null)
158 {
159 if(path == null)
160 {
161 context.put(CATEGORY_NAME, "user");
162 context.put("categoryValue", "anon");
163 context.put("copyFrom", "user/anon/media-type/html/page/default.psml");
164 }
165 else
166 {
167 ProfileLocator tmpLocator = Profiler.createLocator();
168 tmpLocator.createFromPath(path);
169 Profile profile = Profiler.getProfile(tmpLocator);
170 if (profile != null)
171 {
172 rundata.getUser().setTemp(TEMP_LOCATOR, tmpLocator);
173 context.put("profile", profile);
174 }
175 String categoryName = "group";
176 String categoryValue = tmpLocator.getGroupName();
177 if (categoryValue == null)
178 {
179 categoryName = "role";
180 categoryValue = tmpLocator.getRoleName();
181 if (categoryValue == null)
182 {
183 categoryName = "user";
184 categoryValue = tmpLocator.getUserName();
185 if (categoryValue == null)
186 {
187 categoryName = "user";
188 categoryValue = "anon";
189 }
190 }
191
192 }
193 context.put(CATEGORY_NAME, categoryName);
194 context.put("categoryValue", categoryValue);
195 context.put("copyFrom", path);
196 }
197 }
198 else
199 {
200 context.put(CATEGORY_NAME, rundata.getUser().getTemp(CATEGORY_NAME));
201 context.put(CATEGORY_VALUE, rundata.getUser().getTemp(CATEGORY_VALUE));
202 context.put(COPY_FROM, rundata.getUser().getTemp(COPY_FROM));
203 }
204 }
205
206 if(mode != null && mode.equals("export"))
207 {
208 if (msgid == null)
209 {
210 String tmpPath = JetspeedResources.getString(JetspeedResources.TEMP_DIRECTORY_KEY, "/tmp");
211 String exportPath = JetspeedResources.getString("psml.export.default.path",
212 TurbineServlet.getRealPath(tmpPath));
213 if(path == null)
214 {
215 context.put(COPY_TO, exportPath);
216 context.put(COPY_FROM,
217 Profiler.PARAM_USER +
218 File.separator +
219 Profiler.PARAM_ANON +
220 File.separator +
221 Profiler.PARAM_MEDIA_TYPE +
222 File.separator +
223 "html" +
224 File.separator +
225 Profiler.PARAM_PAGE +
226 File.separator +
227 Profiler.FULL_DEFAULT_PROFILE);
228 }
229 else
230 {
231 ProfileLocator tmpLocator = Profiler.createLocator();
232 tmpLocator.createFromPath(path);
233 Profile profile = Profiler.getProfile(tmpLocator);
234 if (profile != null)
235 {
236 rundata.getUser().setTemp(TEMP_LOCATOR, tmpLocator);
237 context.put("profile", profile);
238 }
239
240 String categoryName = Profiler.PARAM_GROUP;
241 String categoryValue = tmpLocator.getGroupName();
242 if (categoryValue == null)
243 {
244 categoryName = Profiler.PARAM_ROLE;
245 categoryValue = tmpLocator.getRoleName();
246 if (categoryValue == null)
247 {
248 categoryName = Profiler.PARAM_USER;
249 categoryValue = tmpLocator.getUserName();
250 if (categoryValue == null)
251 {
252 categoryName = Profiler.PARAM_USER;
253 categoryValue = Profiler.PARAM_ANON;
254 }
255 }
256
257 }
258
259 context.put(COPY_TO, exportPath + File.separator + tmpLocator.getName());
260 context.put(COPY_FROM, path);
261 }
262 }
263 else
264 {
265 context.put(COPY_TO, rundata.getUser().getTemp(COPY_TO));
266 context.put(COPY_FROM, rundata.getUser().getTemp(COPY_FROM));
267 }
268 }
269
270 if(mode != null && mode.equals("export_all"))
271 {
272 if (msgid == null)
273 {
274
275 ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
276 .getResources(PsmlManagerService.SERVICE_NAME);
277 String root = serviceConf.getString("root", "/WEB-INF/psml");
278 context.put(COPY_TO, TurbineServlet.getRealPath(root));
279 }
280 else
281 {
282 context.put(COPY_TO, rundata.getUser().getTemp(COPY_TO));
283 }
284 }
285
286 if(mode != null && mode.equals("import"))
287 {
288 org.apache.jetspeed.om.registry.Registry mediaTypes = Registry.get(Registry.MEDIA_TYPE);
289 context.put("mediaTypes", mediaTypes.listEntryNames());
290 if (msgid == null)
291 {
292
293 ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
294 .getResources(PsmlManagerService.SERVICE_NAME);
295 String root = serviceConf.getString("root", "/WEB-INF/psml");
296 root = TurbineServlet.getRealPath(root);
297
298 if(path == null)
299 {
300 context.put(CATEGORY_NAME, Profiler.PARAM_USER);
301 context.put("categoryValue", Profiler.PARAM_ANON);
302 context.put("copyFrom",
303 root +
304 File.separator +
305 Profiler.PARAM_USER +
306 File.separator +
307 Profiler.PARAM_ANON +
308 File.separator +
309 Profiler.PARAM_MEDIA_TYPE +
310 File.separator +
311 "html" +
312 File.separator +
313 Profiler.PARAM_PAGE +
314 File.separator +
315 Profiler.FULL_DEFAULT_PROFILE);
316 }
317 else
318 {
319 ProfileLocator tmpLocator = Profiler.createLocator();
320 tmpLocator.createFromPath(path);
321 Profile profile = Profiler.getProfile(tmpLocator);
322 if (profile != null)
323 {
324 rundata.getUser().setTemp(TEMP_LOCATOR, tmpLocator);
325 context.put("profile", profile);
326 }
327 String categoryName = Profiler.PARAM_GROUP;
328 String categoryValue = tmpLocator.getGroupName();
329 if (categoryValue == null)
330 {
331 categoryName = Profiler.PARAM_ROLE;
332 categoryValue = tmpLocator.getRoleName();
333 if (categoryValue == null)
334 {
335 categoryName = Profiler.PARAM_USER;
336 categoryValue = tmpLocator.getUserName();
337 if (categoryValue == null)
338 {
339 categoryName = Profiler.PARAM_USER;
340 categoryValue = Profiler.PARAM_ANON;
341 }
342 }
343
344 }
345 context.put(CATEGORY_NAME, categoryName);
346 context.put("categoryValue", categoryValue);
347 String filePath = this.mapLocatorToFile(tmpLocator);
348 context.put("copyFrom", root + File.separator + filePath.toString());
349 }
350 }
351 else
352 {
353 context.put(CATEGORY_NAME, rundata.getUser().getTemp(CATEGORY_NAME));
354 context.put(CATEGORY_VALUE, rundata.getUser().getTemp(CATEGORY_VALUE));
355 context.put(COPY_FROM, rundata.getUser().getTemp(COPY_FROM));
356 }
357 }
358
359 if(mode != null && mode.equals("import_all"))
360 {
361 if (msgid == null)
362 {
363
364 ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
365 .getResources(PsmlManagerService.SERVICE_NAME);
366 String root = serviceConf.getString("root", "/WEB-INF/psml");
367 context.put(COPY_FROM, TurbineServlet.getRealPath(root));
368 }
369 else
370 {
371 context.put(COPY_FROM, rundata.getUser().getTemp(COPY_FROM));
372 }
373 }
374
375 }
376 catch (Exception e)
377 {
378 logger.error("Exception", e);
379 rundata.setMessage("Error in PsmlUpdateAction: " + e.toString());
380 rundata.setStackTrace(StringUtils.stackTrace(e), e);
381 rundata.setScreenTemplate(JetspeedResources.getString("template.error","Error"));
382 }
383 }
384
385 /***
386 * Database Insert Action for Psml.
387 *
388 * @param rundata The turbine rundata context for this request.
389 * @param context The velocity context for this request.
390 */
391 public void doInsert(RunData rundata, Context context)
392 throws Exception
393 {
394 Profile profile = null;
395 ProfileLocator locator = null;
396 String categoryName = null;
397 String categoryValue = null;
398 String copyFrom = null;
399 String name = null;
400
401 try
402 {
403 categoryName = rundata.getParameters().getString("CategoryName");
404 categoryValue = rundata.getParameters().getString("CategoryValue");
405 copyFrom = rundata.getParameters().getString("CopyFrom");
406 name = rundata.getParameters().getString("name");
407
408
409
410 locator = Profiler.createLocator();
411 if (categoryName.equalsIgnoreCase(Profiler.PARAM_GROUP))
412 {
413 locator.setGroupByName(categoryValue);
414 }
415 else if (categoryName.equalsIgnoreCase(Profiler.PARAM_ROLE))
416 {
417 locator.setRoleByName(categoryValue);
418 }
419 else if (categoryName.equalsIgnoreCase(Profiler.PARAM_USER))
420 {
421 locator.setUser(JetspeedSecurity.getUser(categoryValue));
422 }
423 else
424 {
425 locator.setAnonymous(true);
426 }
427
428 String tempVar = rundata.getParameters().getString("psml_mediatype");
429 if (tempVar != null && tempVar.trim().length() > 0)
430 {
431 locator.setMediaType(tempVar);
432 }
433
434 tempVar = rundata.getParameters().getString("psml_language");
435 if (tempVar != null && tempVar.trim().length() > 0)
436 {
437 locator.setLanguage(tempVar);
438 }
439
440 tempVar = rundata.getParameters().getString("psml_country");
441 if (tempVar != null && tempVar.trim().length() > 0)
442 {
443 locator.setCountry(tempVar);
444 }
445
446 locator.setName(name);
447
448
449 if (PsmlManager.getDocument(locator) != null )
450 throw new EntityExistsException("Profile:"+locator.getPath()+" Already Exists!");
451
452
453
454 if (name == null || name.trim().length() == 0)
455 {
456 JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
457 DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE)
458 .addPathInfo(SecurityConstants.PARAM_MODE,
459 SecurityConstants.PARAM_MODE_INSERT)
460 .addPathInfo(SecurityConstants.PARAM_MSGID,
461 SecurityConstants.MID_INVALID_ENTITY_NAME);
462 JetspeedLinkFactory.putInstance(link);
463 rundata.setRedirectURI(duri.toString());
464
465
466 if (locator != null)
467 rundata.getUser().setTemp(TEMP_LOCATOR, locator);
468 if (categoryName != null)
469 rundata.getUser().setTemp(CATEGORY_NAME, categoryName);
470 if (categoryValue != null)
471 rundata.getUser().setTemp(CATEGORY_VALUE, categoryValue);
472 if (copyFrom != null)
473 rundata.getUser().setTemp(COPY_FROM, copyFrom);
474 return;
475 }
476
477
478
479
480 ProfileLocator baseLocator = Profiler.createLocator();
481 baseLocator.createFromPath(copyFrom);
482 Profile baseProfile = Profiler.getProfile(baseLocator);
483
484
485
486
487 if(baseProfile != null)
488 {
489 PSMLDocument doc = baseProfile.getDocument();
490 if(doc != null)
491 {
492 Portlets portlets = doc.getPortlets();
493
494 Portlets clonedPortlets = (Portlets) SerializationUtils.clone(portlets);
495 org.apache.jetspeed.util.PortletUtils.regenerateIds(clonedPortlets);
496 profile = Profiler.createProfile(locator, clonedPortlets);
497 }
498 else
499 {
500 profile = Profiler.createProfile(locator, null);
501 }
502 setRefreshPsmlFlag(rundata, TRUE);
503 }
504 else
505 {
506 logger.error("Profile listed in Copy From Not Found!");
507 }
508 }
509 catch (EntityExistsException e)
510 {
511
512 logger.error("Exception", e);
513
514
515
516
517 JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
518 DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE)
519 .addPathInfo(SecurityConstants.PARAM_MODE,
520 SecurityConstants.PARAM_MODE_INSERT)
521 .addPathInfo(SecurityConstants.PARAM_MSGID,
522 SecurityConstants.MID_ENTITY_ALREADY_EXISTS);
523 JetspeedLinkFactory.putInstance(link);
524 rundata.setRedirectURI(duri.toString());
525 }
526 catch (Exception e)
527 {
528
529 logger.error("Exception", e);
530
531
532
533
534 JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
535 DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE)
536 .addPathInfo(SecurityConstants.PARAM_MODE,
537 SecurityConstants.PARAM_MODE_INSERT)
538 .addPathInfo(SecurityConstants.PARAM_MSGID,
539 SecurityConstants.MID_UPDATE_FAILED);
540 JetspeedLinkFactory.putInstance(link);
541 rundata.setRedirectURI(duri.toString());
542 }
543
544 if (locator != null)
545 rundata.getUser().setTemp(TEMP_LOCATOR, locator);
546 if (categoryName != null)
547 rundata.getUser().setTemp(CATEGORY_NAME, categoryName);
548 if (categoryValue != null)
549 rundata.getUser().setTemp(CATEGORY_VALUE, categoryValue);
550 if (copyFrom != null)
551 rundata.getUser().setTemp(COPY_FROM, copyFrom);
552
553 }
554
555 /***
556 * Delete Psml entry
557 */
558 public void doDelete(RunData rundata, Context context) throws Exception
559 {
560 try
561 {
562 ProfileLocator locator = (ProfileLocator)rundata.getUser().getTemp(TEMP_LOCATOR);
563 if (locator != null)
564 {
565 Profiler.removeProfile(locator);
566 setRefreshPsmlFlag(rundata, TRUE);
567 }
568 else
569 {
570 logger.error("ProfileLocator not found!");
571 }
572 }
573 catch(Exception e)
574 {
575
576 logger.error("Exception", e);
577
578
579
580
581 JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
582 DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE)
583 .addPathInfo(SecurityConstants.PARAM_MODE, SecurityConstants.PARAM_MODE_DELETE)
584 .addPathInfo(SecurityConstants.PARAM_MSGID,
585 SecurityConstants.MID_DELETE_FAILED);
586 JetspeedLinkFactory.putInstance(link);
587 rundata.setRedirectURI(duri.toString());
588 }
589
590 }
591
592 public void setRefreshPsmlFlag(RunData rundata, String value)
593 {
594 rundata.getUser().setTemp(PSML_REFRESH_FLAG, TRUE);
595 }
596
597 /***
598 * File Export Action for Psml.
599 *
600 * @param rundata The turbine rundata context for this request.
601 * @param context The velocity context for this request.
602 */
603 public void doExport(RunData rundata, Context context)
604 throws Exception
605 {
606 Profile profile = null;
607 ProfileLocator locator = null;
608 String copyTo = null;
609 String copyFrom = null;
610
611 try
612 {
613 copyFrom = rundata.getParameters().getString("CopyFrom");
614 copyTo = rundata.getParameters().getString("CopyTo");
615
616
617
618
619 ProfileLocator baseLocator = Profiler.createLocator();
620 baseLocator.createFromPath(copyFrom);
621 Profile baseProfile = Profiler.getProfile(baseLocator);
622
623
624
625
626 if(baseProfile != null)
627 {
628 PSMLDocument doc = baseProfile.getDocument();
629 if(doc != null)
630 {
631 if (!this.saveDocument(copyTo,doc))
632 throw new Exception("Failed to save PSML document");
633 rundata.addMessage("Profile [" + copyFrom + "] has been saved to disk in [" + copyTo + "]<br>");
634 }
635 }
636 else
637 {
638 logger.error("Profile listed in Copy From Not Found!");
639 }
640 }
641 catch (Exception e)
642 {
643
644 logger.error("Exception", e);
645
646
647
648
649 JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
650 DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE)
651 .addPathInfo(SecurityConstants.PARAM_MODE,
652 "export")
653 .addPathInfo(SecurityConstants.PARAM_MSGID,
654 SecurityConstants.MID_UPDATE_FAILED);
655 JetspeedLinkFactory.putInstance(link);
656 rundata.setRedirectURI(duri.toString());
657 }
658
659 if (copyTo != null)
660 rundata.getUser().setTemp(COPY_TO, copyTo);
661 if (copyFrom != null)
662 rundata.getUser().setTemp(COPY_FROM, copyFrom);
663
664 }
665
666 /***
667 * File Export All Action for Psml.
668 *
669 * @param rundata The turbine rundata context for this request.
670 * @param context The velocity context for this request.
671 */
672 public void doExportall(RunData rundata, Context context)
673 throws Exception
674 {
675 String copyTo = null;
676
677 logger.info("PsmlUpdateAction: Starting export all operation");
678
679 try
680 {
681 copyTo = rundata.getParameters().getString("CopyTo");
682
683
684
685
686 Iterator i = Profiler.query(new QueryLocator(QueryLocator.QUERY_ALL));
687 while (i.hasNext())
688 {
689 Profile profile = (Profile) i.next();
690 PSMLDocument doc = profile.getDocument();
691 if(doc != null)
692 {
693
694 StringBuffer copyToFile = new StringBuffer(copyTo);
695 copyToFile.append(File.separator);
696 if (profile.getGroupName() != null)
697 {
698 copyToFile.append("group");
699 copyToFile.append(File.separator);
700 copyToFile.append(profile.getGroupName());
701 copyToFile.append(File.separator);
702 }
703 else if (profile.getRoleName() != null)
704 {
705 copyToFile.append("role");
706 copyToFile.append(File.separator);
707 copyToFile.append(profile.getRoleName());
708 copyToFile.append(File.separator);
709 }
710 else if (profile.getUserName() != null)
711 {
712 copyToFile.append("user");
713 copyToFile.append(File.separator);
714 copyToFile.append(profile.getUserName());
715 copyToFile.append(File.separator);
716 }
717 if (profile.getMediaType() != null)
718 {
719 copyToFile.append(profile.getMediaType());
720 copyToFile.append(File.separator);
721 }
722 if (profile.getLanguage() != null)
723 {
724 copyToFile.append(profile.getLanguage());
725 copyToFile.append(File.separator);
726 }
727 if (profile.getCountry() != null)
728 {
729 copyToFile.append(profile.getCountry());
730 copyToFile.append(File.separator);
731 }
732 copyToFile.append(profile.getName());
733
734 if (!this.saveDocument(copyToFile.toString(), doc)) {
735 logger.error("Failed to save PSML document for [" + profile.getPath());
736 } else {
737 String msg = "Profile [" + profile.getPath() + "] has been saved to disk in [" + copyToFile.toString() + "]<br>";
738 logger.info(msg);
739 rundata.addMessage(msg);
740 }
741 }
742 }
743
744 }
745 catch (Exception e)
746 {
747
748 logger.error("Exception", e);
749
750
751
752
753 JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
754 DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE)
755 .addPathInfo(SecurityConstants.PARAM_MODE,
756 "export_all")
757 .addPathInfo(SecurityConstants.PARAM_MSGID,
758 SecurityConstants.MID_UPDATE_FAILED);
759 JetspeedLinkFactory.putInstance(link);
760 rundata.setRedirectURI(duri.toString());
761 }
762
763 if (copyTo != null) {
764 rundata.getUser().setTemp(COPY_TO, copyTo);
765 }
766
767 logger.info("PsmlUpdateAction: Ending export all operation");
768 }
769
770 /*** Save the PSML document on disk to the specififed fileOrUrl
771 *
772 * @param fileOrUrl a String representing either an absolute URL
773 * or an absolute filepath
774 * @param doc the document to save
775 */
776 private boolean saveDocument(String fileOrUrl, PSMLDocument doc)
777 {
778 boolean success = false;
779
780 if (doc == null) return false;
781 File f = new File(fileOrUrl);
782 File d = new File(f.getParent());
783 d.mkdirs();
784
785 FileWriter writer = null;
786
787 try
788 {
789 writer = new FileWriter(f);
790
791 OutputFormat format = new OutputFormat();
792 format.setIndenting(true);
793 format.setIndent(4);
794 Serializer serializer = new XMLSerializer(writer,format);
795 Marshaller marshaller = new Marshaller(serializer.asDocumentHandler());
796 marshaller.setMapping(this.loadMapping());
797 marshaller.marshal(doc.getPortlets());
798
799 success = true;
800 }
801 catch (MarshalException e)
802 {
803 logger.error("PSMLUpdateAction: Could not marshal the file " + f.getAbsolutePath(), e);
804 }
805 catch (MappingException e)
806 {
807 logger.error("PSMLUpdateAction: Could not marshal the file " + f.getAbsolutePath(), e);
808 }
809 catch (ValidationException e)
810 {
811 logger.error("PSMLUpdateAction: document "+f.getAbsolutePath() + " is not valid", e);
812 }
813 catch (IOException e)
814 {
815 logger.error("PSMLUpdateAction: Could not save the file " + f.getAbsolutePath(), e);
816 }
817 catch (Exception e)
818 {
819 logger.error("PSMLUpdateAction: Error while saving " + f.getAbsolutePath(), e);
820 }
821 finally
822 {
823 try
824 {
825 writer.close();
826 }
827 catch (IOException e)
828 {
829 }
830 }
831
832 return success;
833 }
834
835 /***
836 * Loads psml mapping file
837 *
838 * @exception Exception
839 */
840 private Mapping loadMapping()
841 throws Exception
842 {
843
844 ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
845 .getResources(PsmlManagerService.SERVICE_NAME);
846
847
848 Mapping mapping = null;
849 String mapFile = serviceConf.getString("mapping","${webappRoot}/WEB-INF/conf/psml-mapping.xml");
850 mapFile = TurbineServlet.getRealPath( mapFile );
851 if (mapFile != null)
852 {
853 File map = new File(mapFile);
854 if ( logger.isDebugEnabled() )
855 {
856 logger.debug( "Loading psml mapping file " + mapFile );
857 }
858 if (map.exists() && map.isFile() && map.canRead())
859 {
860 try
861 {
862 mapping = new Mapping();
863 InputSource is = new InputSource( new FileReader(map) );
864 is.setSystemId( mapFile );
865 mapping.loadMapping( is );
866 }
867 catch (Exception e)
868 {
869 logger.error("Error in psml mapping creation", e);
870 throw new Exception("Error in mapping");
871 }
872 }
873 else
874 {
875 throw new Exception("PSML Mapping not found or not a file or unreadable: " + mapFile);
876 }
877 }
878
879 return mapping;
880 }
881
882 /***
883 * File Import Action for Psml.
884 *
885 * TODO: Implement file upload.
886 *
887 * @param rundata The turbine rundata context for this request.
888 * @param context The velocity context for this request.
889 */
890 public void doImport(RunData rundata, Context context)
891 throws Exception
892 {
893 Profile profile = null;
894 ProfileLocator locator = null;
895 String categoryName = null;
896 String categoryValue = null;
897 String copyFrom = null;
898 String name = null;
899
900 try
901 {
902 categoryName = rundata.getParameters().getString("CategoryName");
903 categoryValue = rundata.getParameters().getString("CategoryValue");
904 copyFrom = rundata.getParameters().getString("CopyFrom");
905 name = rundata.getParameters().getString("name");
906
907
908
909 locator = Profiler.createLocator();
910 if (categoryName.equalsIgnoreCase(Profiler.PARAM_GROUP))
911 {
912 locator.setGroupByName(categoryValue);
913 }
914 else if (categoryName.equalsIgnoreCase(Profiler.PARAM_ROLE))
915 {
916 locator.setRoleByName(categoryValue);
917 }
918 else if (categoryName.equalsIgnoreCase(Profiler.PARAM_USER))
919 {
920 locator.setUser(JetspeedSecurity.getUser(categoryValue));
921 }
922 else
923 {
924 locator.setAnonymous(true);
925 }
926
927 String tempVar = rundata.getParameters().getString("psml_mediatype");
928 if (tempVar != null && tempVar.trim().length() > 0)
929 {
930 locator.setMediaType(tempVar);
931 }
932
933 tempVar = rundata.getParameters().getString("psml_language");
934 if (tempVar != null && tempVar.trim().length() > 0)
935 {
936 locator.setLanguage(tempVar);
937 }
938
939 tempVar = rundata.getParameters().getString("psml_country");
940 if (tempVar != null && tempVar.trim().length() > 0)
941 {
942 locator.setCountry(tempVar);
943 }
944
945 locator.setName(name);
946
947
948
949
950 if (name == null || name.trim().length() == 0)
951 {
952 JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
953 DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE)
954 .addPathInfo(SecurityConstants.PARAM_MODE,
955 "import")
956 .addPathInfo(SecurityConstants.PARAM_MSGID,
957 SecurityConstants.MID_INVALID_ENTITY_NAME);
958 JetspeedLinkFactory.putInstance(link);
959 rundata.setRedirectURI(duri.toString());
960
961
962 if (locator != null)
963 {
964 rundata.getUser().setTemp(TEMP_LOCATOR, locator);
965 }
966 if (categoryName != null)
967 {
968 rundata.getUser().setTemp(CATEGORY_NAME, categoryName);
969 }
970 if (categoryValue != null)
971 {
972 rundata.getUser().setTemp(CATEGORY_VALUE, categoryValue);
973 }
974 if (copyFrom != null)
975 {
976 rundata.getUser().setTemp(COPY_FROM, copyFrom);
977 }
978 return;
979 }
980
981
982
983
984 PSMLDocument doc = this.loadDocument(copyFrom);
985
986
987
988
989 if(doc != null)
990 {
991 Portlets portlets = doc.getPortlets();
992
993
994
995 if (PsmlManager.getDocument(locator) != null)
996 {
997 Profiler.removeProfile(locator);
998 }
999
1000 Portlets clonedPortlets = (Portlets) SerializationUtils.clone(portlets);
1001 org.apache.jetspeed.util.PortletUtils.regenerateIds(clonedPortlets);
1002
1003 profile = Profiler.createProfile(locator, clonedPortlets);
1004 }
1005 else
1006 {
1007 throw new Exception("Failed to load PSML document from disk");
1008 }
1009 rundata.addMessage("Profile for [" + locator.getPath() + "] has been imported from file [" + copyFrom + "]<br>");
1010 setRefreshPsmlFlag(rundata, TRUE);
1011
1012 }
1013 catch (Exception e)
1014 {
1015
1016 logger.error("Exception", e);
1017
1018
1019
1020
1021 JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
1022 DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE)
1023 .addPathInfo(SecurityConstants.PARAM_MODE,
1024 "import")
1025 .addPathInfo(SecurityConstants.PARAM_MSGID,
1026 SecurityConstants.MID_UPDATE_FAILED);
1027 JetspeedLinkFactory.putInstance(link);
1028 rundata.setRedirectURI(duri.toString());
1029 }
1030
1031 if (locator != null)
1032 {
1033 rundata.getUser().setTemp(TEMP_LOCATOR, locator);
1034 }
1035 if (categoryName != null)
1036 {
1037 rundata.getUser().setTemp(CATEGORY_NAME, categoryName);
1038 }
1039 if (categoryValue != null)
1040 {
1041 rundata.getUser().setTemp(CATEGORY_VALUE, categoryValue);
1042 }
1043 if (copyFrom != null)
1044 {
1045 rundata.getUser().setTemp(COPY_FROM, copyFrom);
1046 }
1047
1048 }
1049
1050 /***
1051 * File Import All Action for Psml.
1052 *
1053 *
1054 * @param rundata The turbine rundata context for this request.
1055 * @param context The velocity context for this request.
1056 */
1057 public void doImportall(RunData rundata, Context context)
1058 throws Exception
1059 {
1060 String copyFrom = null;
1061
1062 try
1063 {
1064 copyFrom = rundata.getParameters().getString("CopyFrom");
1065
1066
1067
1068
1069 Vector files = new Vector();
1070 this.collectPsml(files, copyFrom);
1071
1072
1073
1074
1075 for (Iterator it = files.iterator(); it.hasNext(); )
1076 {
1077
1078 String path = null;
1079 try
1080 {
1081 String psml = ((File) it.next()).getPath();
1082 path = psml.substring(copyFrom.length() + 1);
1083 ProfileLocator locator = this.mapFileToLocator(path);
1084
1085 PSMLDocument doc = this.loadDocument(psml);
1086
1087
1088
1089
1090 if(doc != null)
1091 {
1092 Portlets portlets = doc.getPortlets();
1093
1094
1095
1096 if (PsmlManager.getDocument(locator) != null)
1097 {
1098 Profiler.removeProfile(locator);
1099 }
1100 Profiler.createProfile(locator, portlets);
1101 }
1102 else
1103 {
1104 throw new Exception("Failed to load PSML document [" + psml + "] from disk");
1105 }
1106 rundata.addMessage("Profile for [" + locator.getPath() + "] has been imported from file [" + psml + "]<br>");
1107 setRefreshPsmlFlag(rundata, TRUE);
1108 }
1109 catch (Exception ouch)
1110 {
1111 logger.error("Exception", ouch);
1112 rundata.addMessage("ERROR importing file [" + path + "]: " + ouch.toString() + "<br>");
1113 }
1114 }
1115
1116 }
1117 catch (Exception e)
1118 {
1119
1120 logger.error("Exception", e);
1121
1122
1123
1124
1125 JetspeedLink link = JetspeedLinkFactory.getInstance(rundata);
1126 DynamicURI duri = link.getPaneByName(PSML_UPDATE_PANE)
1127 .addPathInfo(SecurityConstants.PARAM_MODE,
1128 "import_all")
1129 .addPathInfo(SecurityConstants.PARAM_MSGID,
1130 SecurityConstants.MID_UPDATE_FAILED);
1131 JetspeedLinkFactory.putInstance(link);
1132 rundata.setRedirectURI(duri.toString());
1133 }
1134
1135 if (copyFrom != null)
1136 {
1137 rundata.getUser().setTemp(COPY_FROM, copyFrom);
1138 }
1139
1140 }
1141
1142 /***
1143 * This method recursively collect all .psml documents starting at the given root
1144 *
1145 * @param v Vector to put the file into
1146 * @param root Root directory for import
1147 */
1148 private void collectPsml(Vector v, String root)
1149 {
1150
1151 File dir = new File(root);
1152 File[] files = dir.listFiles();
1153 for (int i = 0; i < files.length; i++)
1154 {
1155 if (files[i].isDirectory())
1156 {
1157 collectPsml(v, files[i].getPath());
1158 }
1159 else if (files[i].isFile() && files[i].getPath().endsWith(".psml"))
1160 {
1161 v.add(files[i]);
1162 }
1163 }
1164
1165 }
1166
1167 /***
1168 * Creates profile locator from a given path in the format:
1169 *
1170 * user/<name>/<mediaType>/<language>/<country>/<page>/
1171 *
1172 * group/ ""
1173 * role/ ""
1174 *
1175 * @param path The formatted profiler path string.
1176 * @param path fully qualified .psml file name
1177 * @return profile locator
1178 */
1179 private ProfileLocator mapFileToLocator(String path)
1180 throws Exception
1181 {
1182 if (logger.isDebugEnabled())
1183 {
1184 logger.debug("PsmlUpdateAction.createFromPath: processing path = " + path);
1185 }
1186 ProfileLocator result = Profiler.createLocator();
1187
1188
1189 StringTokenizer tok = new StringTokenizer(path, File.separator);
1190
1191
1192 Vector tokens = new Vector();
1193 while (tok.hasMoreTokens())
1194 {
1195 tokens.add(tok.nextToken());
1196 }
1197
1198
1199 if (tokens.size() > 1)
1200 {
1201 String type = (String) tokens.elementAt(0);
1202 String name = (String) tokens.elementAt(1);
1203 if (type.equals(Profiler.PARAM_USER))
1204 {
1205 result.setUser(JetspeedSecurity.getUser(name));
1206 }
1207 else if (type.equals(Profiler.PARAM_GROUP))
1208 {
1209 result.setGroup(JetspeedSecurity.getGroup(name));
1210 }
1211 else if (type.equals(Profiler.PARAM_ROLE))
1212 {
1213 result.setRole(JetspeedSecurity.getRole(name));
1214 }
1215 }
1216
1217
1218 if (tokens.size() > 0)
1219 {
1220 result.setName((String) tokens.lastElement());
1221 }
1222
1223
1224 switch (tokens.size())
1225 {
1226 case 3:
1227 break;
1228 case 4:
1229 result.setMediaType((String) tokens.elementAt(2));
1230 break;
1231 case 5:
1232 result.setMediaType((String) tokens.elementAt(2));
1233 result.setLanguage((String) tokens.elementAt(3));
1234 break;
1235 case 6:
1236 result.setMediaType((String) tokens.elementAt(2));
1237 result.setLanguage((String) tokens.elementAt(3));
1238 result.setCountry((String) tokens.elementAt(4));
1239 break;
1240 default:
1241 throw new Exception("Path must contain 3 to 6 elements: [" + path + "], and the size was: " + tokens.size());
1242 }
1243
1244 return result;
1245 }
1246
1247 /***
1248 * Maps a ProfileLocator to a file.
1249 *
1250 * @param locator The profile locator describing the PSML resource to be found.
1251 * @return the String path of the file.
1252 */
1253 private String mapLocatorToFile(ProfileLocator locator)
1254 {
1255 StringBuffer path = new StringBuffer();
1256
1257
1258 Role role = locator.getRole();
1259 Group group = locator.getGroup();
1260 JetspeedUser user = locator.getUser();
1261
1262 if (user != null)
1263 {
1264 path.append(Profiler.PARAM_USER);
1265 String name = user.getUserName();
1266 if (null != name && name.length() > 0)
1267 {
1268 path.append(File.separator)
1269 .append(name);
1270 }
1271 }
1272 else if (group != null)
1273 {
1274 path.append(Profiler.PARAM_GROUP);
1275 String name = group.getName();
1276 if (null != name && name.length() > 0)
1277 {
1278 path.append(File.separator)
1279 .append(name);
1280 }
1281 }
1282 else if (null != role)
1283 {
1284 path.append(Profiler.PARAM_ROLE);
1285 String name = role.getName();
1286 if (null != name && name.length() > 0)
1287 {
1288 path.append(File.separator)
1289 .append(name);
1290 }
1291 }
1292
1293
1294 if (null != locator.getMediaType())
1295 {
1296 path.append(File.separator)
1297 .append(locator.getMediaType());
1298 }
1299
1300 if (null != locator.getLanguage())
1301 {
1302 path.append(File.separator)
1303 .append(locator.getLanguage());
1304 }
1305
1306 if (null != locator.getCountry())
1307 {
1308 path.append(File.separator)
1309 .append(locator.getCountry());
1310 }
1311
1312 if (null != locator.getName())
1313 {
1314 if (!(locator.getName().endsWith(Profiler.DEFAULT_EXTENSION)))
1315 {
1316 path.append(File.separator)
1317 .append(locator.getName()).append(Profiler.DEFAULT_EXTENSION);
1318 }
1319 else
1320 {
1321 path.append(File.separator)
1322 .append(locator.getName());
1323 }
1324 }
1325 else
1326 {
1327 path.append(File.separator)
1328 .append(Profiler.FULL_DEFAULT_PROFILE);
1329 }
1330
1331 return path.toString();
1332 }
1333
1334 /***
1335 * Load a PSMLDOcument from disk
1336 *
1337 * @param fileOrUrl a String representing either an absolute URL or an
1338 * absolute filepath
1339 */
1340 private PSMLDocument loadDocument(String fileOrUrl)
1341 {
1342 PSMLDocument doc = null;
1343
1344 if (fileOrUrl != null)
1345 {
1346
1347
1348 File f = null;
1349
1350 f = new File(fileOrUrl);
1351
1352 if (!f.exists())
1353 {
1354 return null;
1355 }
1356
1357 doc = new BasePSMLDocument();
1358 doc.setName(fileOrUrl);
1359
1360
1361 Portlets portlets = null;
1362 FileReader reader = null;
1363 try
1364 {
1365 reader = new FileReader(f);
1366
1367 Unmarshaller unmarshaller = new Unmarshaller(this.loadMapping());
1368 portlets = (Portlets) unmarshaller.unmarshal(reader);
1369
1370 doc.setPortlets(portlets);
1371
1372 }
1373 catch (IOException e)
1374 {
1375 logger.error("PSMLUpdateAction: Could not load the file " + f.getAbsolutePath(), e);
1376 }
1377 catch (MarshalException e)
1378 {
1379 logger.error("PSMLUpdateAction: Could not unmarshal the file " + f.getAbsolutePath(), e);
1380 }
1381 catch (MappingException e)
1382 {
1383 logger.error("PSMLUpdateAction: Could not unmarshal the file " + f.getAbsolutePath(), e);
1384 }
1385 catch (ValidationException e)
1386 {
1387 logger.error("PSMLUpdateAction: document " + f.getAbsolutePath() + " is not valid", e);
1388 }
1389 catch (Exception e)
1390 {
1391 logger.error("PSMLUpdateAction: Error while loading " + f.getAbsolutePath(), e);
1392 }
1393 finally
1394 {
1395 try
1396 {
1397 reader.close();
1398 }
1399 catch (IOException e)
1400 {
1401 }
1402 }
1403 }
1404
1405 return doc;
1406 }
1407
1408 }
1409
1410