1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.services.profiler;
18
19
20 import java.util.Iterator;
21 import java.util.LinkedList;
22 import java.util.List;
23 import java.util.Locale;
24 import java.util.Vector;
25
26 import javax.servlet.ServletConfig;
27
28 import org.apache.commons.lang.SerializationUtils;
29 import org.apache.jetspeed.capability.CapabilityMap;
30 import org.apache.jetspeed.capability.CapabilityMapFactory;
31 import org.apache.jetspeed.om.profile.BasePSMLDocument;
32 import org.apache.jetspeed.om.profile.Control;
33 import org.apache.jetspeed.om.profile.Controller;
34 import org.apache.jetspeed.om.profile.PSMLDocument;
35 import org.apache.jetspeed.om.profile.Portlets;
36 import org.apache.jetspeed.om.profile.Profile;
37 import org.apache.jetspeed.om.profile.ProfileException;
38 import org.apache.jetspeed.om.profile.ProfileLocator;
39 import org.apache.jetspeed.om.profile.QueryLocator;
40 import org.apache.jetspeed.om.profile.Skin;
41 import org.apache.jetspeed.om.profile.psml.PsmlControl;
42 import org.apache.jetspeed.om.profile.psml.PsmlController;
43 import org.apache.jetspeed.om.profile.psml.PsmlPortlets;
44 import org.apache.jetspeed.om.profile.psml.PsmlSkin;
45 import org.apache.jetspeed.om.security.Group;
46 import org.apache.jetspeed.om.security.GroupRole;
47 import org.apache.jetspeed.om.security.JetspeedUser;
48 import org.apache.jetspeed.om.security.Role;
49 import org.apache.jetspeed.services.JetspeedSecurity;
50 import org.apache.jetspeed.services.PortalToolkit;
51 import org.apache.jetspeed.services.Profiler;
52 import org.apache.jetspeed.services.PsmlManager;
53 import org.apache.jetspeed.services.ServiceHelper;
54 import org.apache.jetspeed.services.customlocalization.CustomLocalizationService;
55 import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
56 import org.apache.jetspeed.services.logging.JetspeedLogger;
57 import org.apache.jetspeed.services.rundata.JetspeedRunData;
58 import org.apache.jetspeed.util.MimeType;
59 import org.apache.jetspeed.util.ServiceUtil;
60 import org.apache.turbine.services.InitializationException;
61 import org.apache.turbine.services.TurbineBaseService;
62 import org.apache.turbine.services.TurbineServices;
63 import org.apache.turbine.services.localization.LocalizationService;
64 import org.apache.turbine.services.resources.ResourceService;
65 import org.apache.turbine.services.resources.TurbineResources;
66 import org.apache.turbine.util.DynamicURI;
67 import org.apache.turbine.util.RunData;
68 /***
69 * <p>This is an implementation of the <code>Profiler</code> interface.
70 *
71 * This implementation maps requests to profiles (PSML resources) based on
72 * request parameters, requesting deviced capabilities, and the device's
73 * language. </p>
74 * <p>This service expects these properties to be set for correct operation:
75 * <dl>
76 * <dt>root</dt><dd>The webapp rel. path to the root profiling directory</dd>
77 * <dt>resource.default</dt><dd>The default resource filename</dd>
78 * <dt>resource.ext</dt><dd>The default resource filename extension</dd>
79 * <dt>security</dt><dd>Use security flag</dd>
80 * <dt>fallback.language</dt><dd>Use language configuration flag</dd>
81 * <dt>fallback.country</dt><dd>Use country configuration flag</dd>
82 * <dt>fallback.to.root</dt><dd>Continue falling back past media type flag</dd>
83 *
84 * </dl>
85 * </p>
86 *
87 * @author <a href="mailto:david@bluesunrise.com">David Sean Taylor</a>
88 * @author <a href="mailto:sgala@hisitech.com">Santiago Gala</a>
89 * @author <a href="mailto:morciuch@apache.org">Mark Orciuch</a>
90 * @version $Id: JetspeedProfilerService.java,v 1.56 2004/02/23 03:35:24 jford Exp $
91 */
92
93 public class JetspeedProfilerService extends TurbineBaseService
94 implements ProfilerService
95 {
96 /***
97 * Static initialization of the logger for this class
98 */
99 private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(JetspeedProfilerService.class.getName());
100
101
102 private final static String CONFIG_RESOURCE_DEFAULT = "resource.default";
103 private final static String CONFIG_RESOURCE_EXT = "resource.ext";
104 private final static String CONFIG_SECURITY = "security";
105 private final static String CONFIG_ROLE_FALLBACK = "rolefallback";
106 private final static String CONFIG_NEWUSER_TEMPLATE = "newuser.template";
107 private final static String CONFIG_NEWUSER_MEDIA = "newuser.media_types";
108 private final static String CONFIG_FALLBACK_LANGUAGE = "fallback.language";
109 private final static String CONFIG_FALLBACK_COUNTRY = "fallback.country";
110 private final static String CONFIG_FALLBACK_TO_ROOT = "fallback.to.root";
111 private final static String CONFIG_ROLE_MERGE = "rolemerge";
112 private final static String CONFIG_ROLE_MERGE_CONTROL = "rolemerge.control";
113 private final static String CONFIG_ROLE_MERGE_CONTROLLER = "rolemerge.controller";
114
115
116 private final static String DEFAULT_CONFIG_RESOURCE_DEFAULT = "default";
117 private final static String DEFAULT_CONFIG_RESOURCE_EXT = ".psml";
118 private final static boolean DEFAULT_CONFIG_SECURITY = false;
119 private final static boolean DEFAULT_CONFIG_ROLE_FALLBACK = true;
120 private final static String DEFAULT_CONFIG_NEWUSER_TEMPLATE = null;
121 private final static String [] DEFAULT_CONFIG_NEWUSER_MEDIA =
122 { "html", "wml" };
123 private final static String DEFAULT_CONFIG_ROLE_MERGE_CONTROL = "TabControl";
124 private final static String DEFAULT_CONFIG_ROLE_MERGE_CONTROLLER = "TabController";
125
126 private final static String PATH_EXTENSION_DELIMITER = ".";
127
128 private final static String MSG_MISSING_PARAMETER =
129 "JetspeedProfilerService initialization failed. Missing parameter:";
130
131
132 private Class profileClass = null;
133 private Class locatorClass = null;
134
135
136
137 String root;
138 String resourceDefault;
139 String resourceExt;
140 String rolemergeControl;
141 String rolemergeController;
142
143
144 String newUserTemplate = DEFAULT_CONFIG_NEWUSER_TEMPLATE;
145
146 boolean useSecurity = false;
147 boolean useRoleFallback = true;
148 boolean useFallbackLanguage = true;
149 boolean useFallbackCountry = true;
150 boolean useFallbackToRoot = false;
151 boolean useRoleMerge = false;
152
153 String mediaTypes[] = null;
154
155 /***
156 * This methode creates a wml profile and a html profile
157 * for a new user
158 * --------------------------------------------------------------------------
159 * last modified: 10/31/01
160 * Andreas Kempf, Siemens ICM S CP PE, Munich
161 * mailto: A.Kempf@web.de
162 */
163 public Profile createProfile(RunData data, Profile profile)
164 throws ProfileException
165 {
166 Profile current = null;
167 CapabilityMap map;
168
169 if (data == null)
170 {
171 map = CapabilityMapFactory.getDefaultCapabilityMap();
172 }
173 else
174 {
175 map = ((JetspeedRunData)data).getCapability();
176 }
177 String mediaType = getMediaType(data, map);
178
179
180 if (newUserTemplate == null)
181 return current;
182
183 if (mediaTypes != null)
184 {
185 Profile dummy;
186 for (int ix=0; ix < mediaTypes.length; ix++)
187 {
188 dummy = createProfile(data, profile, mediaTypes[ix], newUserTemplate);
189 if (mediaTypes[ix].equalsIgnoreCase(mediaType))
190 current = dummy;
191 }
192 }
193 return current;
194 }
195
196
197
198 /***
199 * This is the early initialization method called by the
200 * Turbine <code>Service</code> framework
201 * @param conf The <code>ServletConfig</code>
202 * @exception throws a <code>InitializationException</code> if the service
203 * fails to initialize
204 */
205 public synchronized void init(ServletConfig conf) throws InitializationException
206 {
207
208
209 if (getInit()) return;
210
211 try
212 {
213 initConfiguration();
214 }
215 catch (Exception e)
216 {
217 logger.error("Profiler: Failed to load Service ", e);
218 }
219
220
221 setInit(true);
222
223 }
224
225 /***
226 * This is the shutdown method called by the
227 * Turbine <code>Service</code> framework
228 */
229 public void shutdown()
230 {
231 }
232
233 /***
234 * get the Profile object using the Rundata state and capability map
235 * this is the mapping functionality of the profiler
236 *
237 * @param rundata the rundata object for the current request
238 * @param cm the <code>CapabilityMap</code> of the current requesting device
239 * @return a new Profile object
240 */
241 public Profile getProfile(RunData data, CapabilityMap cm)
242 throws ProfileException
243 {
244 JetspeedRunData rundata = (JetspeedRunData)data;
245 Profile profile = fallbackProfile(rundata, cm);
246 if (null == profile && useRoleFallback)
247 {
248 Vector profiles = new Vector();
249 JetspeedUser user = rundata.getJetspeedUser();
250 if (user != null)
251 {
252 try
253 {
254 String paramRole = rundata.getParameters().getString(Profiler.PARAM_ROLE);
255 Iterator groupRoles = JetspeedSecurity.getRoles(user.getUserName());
256 if (groupRoles != null)
257 {
258 while (groupRoles.hasNext())
259 {
260
261 GroupRole gr = (GroupRole) groupRoles.next();
262 rundata.getParameters().setString( Profiler.PARAM_ROLE, gr.getRole().getName() );
263 profile = fallbackProfile(rundata, cm);
264 if (profile != null)
265 {
266 profiles.add(profile);
267 }
268 rundata.getParameters().remove(Profiler.PARAM_ROLE);
269 }
270 profile = mergeRoleProfiles(data, profiles);
271
272
273 if (profile == null)
274 {
275 profile = fallbackProfile(rundata, cm);
276 }
277 }
278
279 rundata.getParameters().setString(Profiler.PARAM_ROLE, paramRole);
280 }
281 catch (Exception e)
282 {
283 logger.error( "Error getting profile", e );
284 throw new ProfileException(e.toString());
285 }
286 }
287 }
288 return profile;
289 }
290
291 /***
292 * Merge role profiles to create default profile. Resulting psml will be a set of
293 * tabs. If role's psml is a tab control, each tab is placed in the resulting psml
294 * as is. Otherwise, a new tab is created and psml is placed there. In this case,
295 * tab name will be derived from role's name. For example, if role name is "news",
296 * the resulting profile name will be "News Home".
297 *
298 * @param data
299 * @param profiles Vector of profiles for all roles user is part of
300 * @return Merged profile
301 * @exception Exception
302 */
303 private Profile mergeRoleProfiles(RunData data, Vector profiles)
304 throws Exception
305 {
306 Profile result = null;
307
308
309 if (!this.useRoleMerge)
310 {
311 if (profiles.size() > 0)
312 {
313 result = (Profile) profiles.get(0);
314 }
315 }
316
317 else if (profiles.size() > 0)
318 {
319 try
320 {
321
322 Portlets portlets = new PsmlPortlets();
323 Control control = new PsmlControl();
324 control.setName(this.rolemergeControl);
325 portlets.setControl(control);
326 Controller controller = new PsmlController();
327 controller.setName(this.rolemergeController);
328 portlets.setController(controller);
329
330
331 Skin skin = new PsmlSkin();
332 skin.setName(PortalToolkit.getSkin((String) null).getName());
333 portlets.setSkin(skin);
334
335 String mediaType = null;
336
337
338 int paneCount = 0;
339 for (Iterator it = profiles.iterator(); it.hasNext(); )
340 {
341 Profile roleProfile = (Profile)it.next();
342 mediaType = mediaType == null ? roleProfile.getMediaType() : mediaType;
343 Profile tmpProfile = (Profile) roleProfile.clone();
344 Portlets tmpPortlets = tmpProfile.getDocument().getPortlets();
345
346
347 Control paneControl = tmpPortlets.getControl();
348 if (paneControl != null && paneControl.getName().equals(this.rolemergeControl))
349 {
350 for (int i = 0; i < tmpPortlets.getPortletsCount(); i++)
351 {
352 Portlets pane = tmpPortlets.getPortlets(i);
353 pane.setLayout(null);
354 portlets.addPortlets(pane);
355 paneCount++;
356 }
357 }
358
359 else
360 {
361 if (tmpPortlets.getTitle() == null)
362 {
363 String title = org.apache.turbine.util.StringUtils.firstLetterCaps(roleProfile.getRoleName());
364 tmpPortlets.setTitle(title + " Home");
365 }
366 tmpPortlets.setLayout(null);
367 portlets.addPortlets(tmpPortlets);
368 paneCount++;
369 }
370
371 if (logger.isDebugEnabled())
372 {
373 logger.debug("Profiler: Processing profile for role " + roleProfile.getRoleName());
374 }
375 }
376
377
378 ProfileLocator locator = createLocator();
379 locator.setUser((JetspeedUser) data.getUser());
380 locator.setMediaType(mediaType);
381 locator.setName(this.resourceDefault + this.resourceExt);
382
383
384 org.apache.jetspeed.util.PortletUtils.regenerateIds(portlets);
385
386
387 result = this.createProfile(locator, portlets);
388
389 }
390 catch (Exception e)
391 {
392 logger.error("Exception", e);
393 }
394 }
395
396 return result;
397 }
398
399 /***
400 * get the Profile object using the Rundata state and capability map
401 * this is the mapping functionality of the profiler
402 *
403 * @param rundata the rundata object for the current request
404 * @param cm the <code>CapabilityMap</code> of the current requesting device
405 * @return a new Profile object
406 */
407 protected Profile fallbackProfile(RunData data, CapabilityMap cm)
408 throws ProfileException
409 {
410 try
411 {
412 JetspeedRunData rundata = (JetspeedRunData)data;
413 Profile profile = createProfile();
414 JetspeedUser user = rundata.getJetspeedUser();
415
416
417 profile.setMediaType(getMediaType(rundata, cm));
418
419
420
421 String param = rundata.getParameters().getString( Profiler.PARAM_GROUP );
422
423 if (null != param)
424 {
425
426 profile.setGroup( JetspeedSecurity.getGroup(param) );
427 }
428 else
429 {
430 param = rundata.getParameters().getString( Profiler.PARAM_ROLE );
431 if (null != param)
432 {
433
434 if (user.hasLoggedIn())
435 {
436 profile.setRole( JetspeedSecurity.getRole(param) );
437 }
438 else
439 {
440 profile.setAnonymous(true);
441 profile.setUser( user );
442 }
443 }
444 else
445 {
446
447 param = rundata.getParameters().getString( Profiler.PARAM_USER );
448 if (null != param)
449 {
450
451 if (param.equals(JetspeedSecurity.getAnonymousUserName()))
452 {
453 profile.setAnonymous(true);
454 }
455 if (user.getUserName().equals(param))
456 {
457 profile.setUser( user );
458 }
459 else
460 {
461 profile.setUser( JetspeedSecurity.getUser(param) );
462 }
463 }
464 else
465 {
466 profile.setAnonymous(user.getUserName().equals(JetspeedSecurity.getAnonymousUserName()));
467 profile.setUser( user );
468 }
469 }
470 }
471
472
473 StringBuffer resource = new StringBuffer();
474 param = rundata.getParameters().getString( Profiler.PARAM_PAGE );
475 if (null == param)
476 {
477
478 resource.append( resourceDefault );
479 resource.append( resourceExt );
480 }
481 else
482 {
483 resource.append( param );
484 if ( -1 == param.indexOf( PATH_EXTENSION_DELIMITER ) )
485 resource.append( resourceExt );
486 }
487 profile.setName( resource.toString() );
488
489
490 getLanguageSettings(profile, rundata);
491
492 PSMLDocument doc = fallback( profile );
493 if (null != doc)
494 {
495 profile.setDocument( doc );
496 return profile;
497 }
498 }
499 catch (Exception e)
500 {
501 logger.error( "Exception in fallbackProfile", e );
502 throw new ProfileException(e.toString());
503 }
504 return null;
505 }
506
507 /***
508 * get the Profile object using the Rundata state and capability map
509 * this is the mapping functionality of the profiler
510 *
511 * @param rundata the rundata object for the current request
512 * @return a new Profile object
513 */
514 public Profile getProfile(RunData rundata)
515 throws ProfileException
516 {
517 CapabilityMap cm = null;
518
519 if (rundata instanceof JetspeedRunData)
520 {
521 cm = ((JetspeedRunData)rundata).getCapability();
522 }
523 else
524 {
525 cm = CapabilityMapFactory.getCapabilityMap( rundata );
526 }
527
528 return getProfile(rundata, cm);
529 }
530
531 /***
532 * get the Profile object using the Rundata state and specific mimetype
533 *
534 * @deprecated Do not use a profiler method based on MimeType
535 *
536 * @param rundata the rundata object for the current request
537 * @param mt the <code>MimeType</code> of the current requesting device
538 * @return a new Profile object
539 */
540 public Profile getProfile(RunData data, MimeType mt)
541 throws ProfileException
542 {
543 CapabilityMap cm = CapabilityMapFactory.getCapabilityMap(mt.toString());
544 return getProfile(data, cm);
545 }
546
547 /***
548 * get the Profile object using a profile locator
549 *
550 * @param rundata The rundata object for the current request.
551 * @param locator The locator containing criteria describing the profile.
552 * @return a new Profile object
553 */
554 public Profile getProfile(ProfileLocator locator)
555 throws ProfileException
556 {
557 PSMLDocument doc = fallback(locator);
558 Profile profile = createProfile(locator);
559 profile.setDocument(doc);
560 return profile;
561 }
562
563
564
565
566
567
568
569 protected void getLanguageSettings( Profile profile, RunData rundata )
570 {
571 String language = rundata.getParameters().getString(Profiler.PARAM_LANGUAGE);
572
573 if (language != null)
574 {
575
576 profile.setLanguage(language);
577
578 if(! language.equals("-1"))
579 {
580 String country = rundata.getParameters().getString(Profiler.PARAM_COUNTRY);
581 if (country != null)
582 {
583 profile.setCountry(country);
584 }
585 }
586 }
587 else
588 {
589 Locale locale = (Locale)rundata.getUser().getTemp("locale");
590 if (locale == null)
591 {
592
593 CustomLocalizationService locService = (CustomLocalizationService) ServiceUtil.getServiceByName(
594 LocalizationService.SERVICE_NAME);
595 locale = locService.getLocale(rundata);
596 if (locale == null)
597 {
598 locale = new Locale(
599 TurbineResources.getString("locale.default.language", "en"),
600 TurbineResources.getString("locale.default.country", "US"));
601 }
602 rundata.getUser().setTemp("locale", locale);
603 }
604
605 if (useFallbackLanguage)
606 {
607 profile.setLanguage( locale.getLanguage() );
608 }
609
610 if (useFallbackCountry)
611 {
612 profile.setCountry( locale.getCountry() );
613 }
614 }
615 }
616
617
618
619
620
621
622
623
624
625
626 protected PSMLDocument fallbackList( ProfileLocator original, RunData rundata )
627 {
628 try
629 {
630 List locators = new LinkedList();
631 ProfileLocator locator = (ProfileLocator)original.clone();
632
633 locators.add( locator.clone() );
634
635
636 if (null != original.getCountry())
637 {
638 locator.setCountry(null);
639 locators.add( locator.clone() );
640 }
641
642
643 if (null != original.getLanguage())
644 {
645 locator.setLanguage(null);
646 locators.add( locator.clone() );
647 }
648
649
650 if (null != original.getMediaType())
651 {
652 locator.setMediaType(null);
653 locators.add( locator.clone() );
654 }
655
656 if (null != original.getGroup())
657 {
658 locator.setGroup(null);
659 locators.add( locator.clone() );
660 }
661 else if (null != original.getRole())
662 {
663 locator.setRole(null);
664 locators.add( locator.clone() );
665 }
666 else if (null != original.getUser())
667 {
668 locator.setUser(null);
669 locators.add( locator.clone() );
670 }
671 PSMLDocument doc = PsmlManager.getDocument( locators );
672 return doc;
673
674 }
675 catch (CloneNotSupportedException e)
676 {
677 logger.error("Profiler: Could not clone profile locator object", e);
678 }
679 return null;
680 }
681
682
683
684
685
686
687
688
689
690
691
692
693 protected PSMLDocument fallback(ProfileLocator locator)
694 {
695 if (logger.isDebugEnabled())
696 {
697 logger.debug( "Profiler: fallback called with: " + locator );
698 }
699
700 PSMLDocument doc = PsmlManager.getDocument( locator );
701 if (null != doc)
702 return doc;
703
704
705 if (null != locator.getCountry() && (! locator.getCountry().equals("-1")))
706 {
707 locator.setCountry(null);
708 doc = PsmlManager.getDocument( locator );
709 if (null != doc)
710 return doc;
711 }
712
713
714 if (null != locator.getLanguage() && (! locator.getLanguage().equals("-1")))
715 {
716 locator.setLanguage(null);
717 doc = PsmlManager.getDocument( locator );
718 if (null != doc)
719 return doc;
720 }
721
722
723 if (useFallbackToRoot)
724 {
725 if (null != locator.getMediaType())
726 {
727 locator.setMediaType(null);
728 doc = PsmlManager.getDocument( locator );
729 if (null != doc)
730 return doc;
731 }
732 }
733
734 if (!useRoleFallback)
735 {
736 if (null != locator.getGroup())
737 {
738 locator.setGroup(null);
739 doc = PsmlManager.getDocument( locator );
740 if (null != doc)
741 return doc;
742 }
743 else if (null != locator.getRole())
744 {
745 locator.setRole(null);
746 doc = PsmlManager.getDocument( locator );
747 if (null != doc)
748 return doc;
749 }
750 else if (null != locator.getUser())
751 {
752 locator.setUser(null);
753 doc = PsmlManager.getDocument( locator );
754 if (null != doc)
755 return doc;
756 }
757 }
758 return doc;
759
760 }
761
762 /***
763 * Lookup the media type from the CapabilitMap.
764 * First the RunData is checked for an explicit media-type request.
765 *
766 * @param cm The <code>CapabilityMap</code> of the current requesting device.
767 * @param rundata, The <code>RunData</code> turbine request context information.
768 * @return a String, the unique name of the media type.
769 */
770 protected String getMediaType(RunData rundata, CapabilityMap cm)
771 {
772 String paramMediaType;
773 String media = null;
774
775 if (null != rundata)
776 {
777 paramMediaType = rundata.getParameters().getString( Profiler.PARAM_MEDIA_TYPE );
778 if (null != paramMediaType)
779 {
780 return paramMediaType;
781 }
782 }
783
784 if (cm != null)
785 {
786 media = cm.getPreferredMediaType();
787 }
788
789 return media;
790 }
791
792 /***
793 * Loads the configuration parameters for this service from the
794 * JetspeedResources.properties file.
795 *
796 * @exception throws a <code>InitializationException</code> if the service
797 * fails to initialize
798 */
799 private void initConfiguration() throws InitializationException
800 {
801 profileClass = ServiceHelper.loadModelClass(this, "profile.impl");
802 locatorClass = ServiceHelper.loadModelClass(this, "locator.impl");
803
804
805 ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
806 .getResources(ProfilerService.SERVICE_NAME);
807
808 resourceDefault = serviceConf.getString( CONFIG_RESOURCE_DEFAULT, DEFAULT_CONFIG_RESOURCE_DEFAULT );
809
810 resourceExt = serviceConf.getString( CONFIG_RESOURCE_EXT, DEFAULT_CONFIG_RESOURCE_EXT );
811 if (-1 == resourceExt.indexOf(PATH_EXTENSION_DELIMITER))
812 {
813 resourceExt = PATH_EXTENSION_DELIMITER + resourceExt;
814 }
815
816 useSecurity = serviceConf.getBoolean( CONFIG_SECURITY, DEFAULT_CONFIG_SECURITY );
817
818 useRoleFallback = serviceConf.getBoolean( CONFIG_ROLE_FALLBACK, DEFAULT_CONFIG_ROLE_FALLBACK );
819
820 newUserTemplate = serviceConf.getString( CONFIG_NEWUSER_TEMPLATE, DEFAULT_CONFIG_NEWUSER_TEMPLATE );
821
822 useFallbackToRoot = serviceConf.getBoolean( CONFIG_FALLBACK_TO_ROOT, useFallbackToRoot );
823
824 useFallbackLanguage = serviceConf.getBoolean( CONFIG_FALLBACK_LANGUAGE, useFallbackLanguage );
825
826 useRoleMerge = serviceConf.getBoolean( CONFIG_ROLE_MERGE, useRoleMerge );
827
828 rolemergeControl = serviceConf.getString( CONFIG_ROLE_MERGE_CONTROL, DEFAULT_CONFIG_ROLE_MERGE_CONTROL );
829
830 rolemergeController = serviceConf.getString( CONFIG_ROLE_MERGE_CONTROLLER, DEFAULT_CONFIG_ROLE_MERGE_CONTROLLER );
831
832 if (useFallbackLanguage == false)
833 {
834 useFallbackCountry = false;
835 }
836 else
837 {
838 useFallbackCountry = serviceConf.getBoolean( CONFIG_FALLBACK_COUNTRY, useFallbackCountry );
839 }
840
841 try
842 {
843 mediaTypes = serviceConf.getStringArray(CONFIG_NEWUSER_MEDIA);
844 }
845 catch (Exception e)
846 {
847 logger.error( "Error getting media types", e );
848 }
849
850 if (null == mediaTypes || mediaTypes.length == 0)
851 {
852 mediaTypes = DEFAULT_CONFIG_NEWUSER_MEDIA;
853 }
854 }
855
856 /***
857 * Builds a dynamic URI based on the current profiler group/role/page
858 *
859 * @param data The rundata object for the current request.
860 * @param locator The description of the profile.
861 * @return A new dynamic URI representing all profile parameters from the locator.
862 */
863 public DynamicURI makeDynamicURI( RunData data, ProfileLocator locator )
864 throws ProfileException
865 {
866 DynamicURI uri = new DynamicURI( data );
867
868
869 String mtype = locator.getMediaType();
870 if (null != mtype)
871 {
872 uri.addPathInfo(Profiler.PARAM_MEDIA_TYPE, mtype);
873 }
874
875
876 String language = locator.getLanguage();
877 if (null != language)
878 {
879 uri.addPathInfo(Profiler.PARAM_LANGUAGE, language);
880 }
881
882
883 String country = locator.getCountry();
884 if (null != country)
885 {
886 uri.addPathInfo(Profiler.PARAM_COUNTRY, country);
887 }
888
889
890 JetspeedUser user = locator.getUser();
891 if (null != user)
892 {
893 if (user.getUserName() != null)
894 uri.addPathInfo(Profiler.PARAM_USER, user.getUserName());
895 }
896 else
897 {
898 Group group = locator.getGroup();
899 if (null != group)
900 {
901 uri.addPathInfo(Profiler.PARAM_GROUP, group.getName());
902 }
903 else
904 {
905 Role role = locator.getRole();
906 if (null != role)
907 {
908 uri.addPathInfo(Profiler.PARAM_ROLE, role.getName());
909 }
910 }
911 }
912
913
914 String page = locator.getName();
915 if (null != page)
916 {
917 uri.addPathInfo(Profiler.PARAM_PAGE, page);
918 }
919
920 return uri;
921 }
922
923 /***
924 * Creates a new Profile object that can be successfully managed by
925 * the current Profiler implementation
926 *
927 * @return A new Profile object
928 */
929 public Profile createProfile()
930 {
931 return (Profile)ServiceHelper.createObject(this.profileClass);
932 }
933
934 /***
935 * Creates a new Profile object for a specific locator.
936 *
937 * @param locator The description of the profile.
938 * @return A new Profile object
939 */
940 public Profile createProfile(ProfileLocator locator)
941 {
942 Profile profile = (Profile)ServiceHelper.createObject(this.profileClass);
943 profile.init(locator);
944 return profile;
945 }
946
947 /***
948 * Creates a new ProfileLocator object that can be successfully managed by
949 * the current Profiler implementation
950 *
951 * @return A new ProfileLocator object
952 */
953 public ProfileLocator createLocator()
954 {
955 return (ProfileLocator)ServiceHelper.createObject(this.locatorClass);
956 }
957
958 /***
959 * Create a new profile given a profile locator
960 *
961 * This method assumes that you have cloned and regenerated the
962 * portlet ids if the portlets come from another profile.
963 *
964 * @param locator The description of the new profile to be created.
965 * @param portlets The PSML tree
966 */
967
968 public Profile createProfile(ProfileLocator locator, Portlets portlets)
969 throws ProfileException
970 {
971 if (portlets == null)
972 {
973 portlets = new PsmlPortlets();
974 }
975
976 Profile profile = createProfile(locator);
977 PSMLDocument doc = new BasePSMLDocument(null, portlets);
978 profile.setDocument(doc);
979 doc = PsmlManager.createDocument(profile);
980 profile.setDocument(doc);
981 return profile;
982 }
983
984 /***
985 * Create a new profile.
986 * The profile parameter's document will be cloned.
987 *
988 * @param rundata The rundata object for the current request.
989 * @param profile The description of the new profile to be created.
990 * @param contentType create a profile for the specific contentType
991 * @param from create a profile by cloning the profile from the specific user (if null - turbine is used)
992 * @return The newly created profile.
993 * -----------------------------------------------------------
994 * Andreas Kempf, Siemens ICM S CP PE, Munich
995 */
996
997 /***
998 * This methode creates a wml profile and a html profile
999 * for a new user
1000 */
1001
1002 public Profile createProfile( RunData data, Profile profile, String contentType, String from )
1003 throws ProfileException
1004 {
1005 if ((contentType == null) || (contentType.length() < 2))
1006 contentType = "html";
1007
1008 if ((from == null) || (from.length() < 2))
1009 from = "turbine";
1010
1011
1012 if ((null == profile.getDocument()) || (!profile.getMediaType().equalsIgnoreCase (contentType)))
1013 {
1014
1015
1016
1017
1018 try
1019 {
1020 ProfileLocator locator = createLocator();
1021 locator.setUser( JetspeedSecurity.getUser(from) );
1022
1023 locator.setMediaType(contentType);
1024 PSMLDocument doc = fallback(locator);
1025
1026 if (doc != null)
1027 {
1028 PSMLDocument clonedDoc = (PSMLDocument) SerializationUtils.clone(doc);
1029 org.apache.jetspeed.util.PortletUtils.regenerateIds(clonedDoc.getPortlets());
1030 profile.setDocument(clonedDoc);
1031 }
1032
1033 profile.setName( resourceDefault + resourceExt );
1034
1035 }
1036 catch (Exception e)
1037 {
1038 logger.error( "Error creating profile", e );
1039 throw new ProfileException(e.toString());
1040 }
1041 }
1042
1043 try
1044 {
1045 profile.setMediaType(contentType);
1046
1047 PSMLDocument doc = PsmlManager.createDocument(profile);
1048 Profile newProfile = (Profile)profile.clone();
1049 newProfile.setDocument(doc);
1050
1051 return newProfile;
1052 }
1053 catch (CloneNotSupportedException e)
1054 {
1055 logger.error("Could not clone profile locator object: ", e);
1056 }
1057 return null;
1058
1059 }
1060
1061 /*** Create a new profile.
1062 *
1063 * @deprecated Should be removed when old customizer is removed.
1064 *
1065 * @param rundata The rundata object for the current request.
1066 * @param profile The description of the new profile to be created.
1067 * @param mt The specific mime type, which is converted to a mediatype.
1068 * @return The newly created profile.
1069 */
1070 public Profile createProfile( RunData data, Profile profile, MimeType mt )
1071 throws ProfileException
1072 {
1073 CapabilityMap cm = CapabilityMapFactory.getCapabilityMap(mt.getContentType());
1074 profile.setMediaType( getMediaType(data, cm) );
1075 return createProfile(data, profile);
1076 }
1077
1078 /***
1079 * Removes a profile.
1080 *
1081 * @param locator The profile locator criteria.
1082 */
1083 public void removeProfile( ProfileLocator locator )
1084 {
1085 PsmlManager.removeDocument(locator);
1086 }
1087
1088 /*** Query for a collection of profiles given a profile locator criteria.
1089 *
1090 * @param locator The profile locator criteria.
1091 * @return The list of profiles matching the locator criteria.
1092 */
1093 public Iterator query( QueryLocator locator )
1094 {
1095 return PsmlManager.query( locator );
1096 }
1097
1098 /***
1099 * @see org.apache.jetspeed.services.profiler.ProfilerService#useRoleProfileMerging
1100 */
1101 public boolean useRoleProfileMerging()
1102 {
1103 return this.useRoleFallback && this.useRoleMerge;
1104 }
1105 }
1106