View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.serializer;
18  
19  import java.util.Collection;
20  import java.util.Iterator;
21  import java.util.Vector;
22  import java.util.prefs.Preferences;
23  
24  import javolution.xml.XMLBinding;
25  
26  import org.apache.jetspeed.components.ComponentManager;
27  import org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent;
28  import org.apache.jetspeed.components.portletregistry.PortletRegistry;
29  import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
30  import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
31  import org.apache.jetspeed.om.preference.impl.PrefsPreference;
32  import org.apache.jetspeed.om.preference.impl.PrefsPreferenceSetImpl;
33  import org.apache.jetspeed.prefs.PreferencesProvider;
34  import org.apache.jetspeed.serializer.objects.JSApplication;
35  import org.apache.jetspeed.serializer.objects.JSApplications;
36  import org.apache.jetspeed.serializer.objects.JSEntities;
37  import org.apache.jetspeed.serializer.objects.JSEntity;
38  import org.apache.jetspeed.serializer.objects.JSEntityPreference;
39  import org.apache.jetspeed.serializer.objects.JSEntityPreferences;
40  import org.apache.jetspeed.serializer.objects.JSNVPElements;
41  import org.apache.jetspeed.serializer.objects.JSPortlet;
42  import org.apache.jetspeed.serializer.objects.JSPortlets;
43  import org.apache.jetspeed.serializer.objects.JSSecondaryData;
44  import org.apache.pluto.om.common.Preference;
45  import org.apache.pluto.om.portlet.PortletDefinition;
46  import org.apache.pluto.om.portlet.PortletDefinitionList;
47  
48  /***
49   * Jetspeed Serializer - Secondary Data
50   * <p>
51   * The Serializer is capable of reading and writing additional content of the
52   * Jetspeed environment such as entities and preferences to and from XML files.
53   * The component can be used from a standalone java application for seeding a
54   * new database or from a running portal as an administrative backup/restore
55   * function.
56   * <p>
57   * 
58   * @author <a href="mailto:hajo@bluesunrise.com">Hajo Birthelmer</a>
59   * @version $Id: $
60   */
61  public class JetspeedSerializerSecondaryImpl extends JetspeedSerializerBase
62  		implements
63  			JetspeedSerializer
64  {
65  
66  	boolean overwrite = true;
67  	int refCouter = 0;
68  
69  	private PortletEntityAccessComponent entityAccess = null;
70  
71  	private PortletRegistry registry;
72  
73  	private PreferencesProvider prefProvider;
74  
75  	protected Class getSerializerDataClass()
76  	{
77  		return JSSecondaryData.class;
78  	}
79  
80  	protected String getSerializerDataTag()
81  	{
82  		return TAG_SECONDARYSNAPSHOT;
83  	}
84  
85  	public JetspeedSerializerSecondaryImpl()
86  	{
87  		super();
88  	}
89  
90  	/***
91  	 * hand over existing component manager
92  	 * 
93  	 * @param cm
94  	 */
95  	public JetspeedSerializerSecondaryImpl(ComponentManager cm)
96  	{
97  		super(cm);
98  	}
99  
100 	/***
101 	 * This constructor takes the application root, the search path for the boot
102 	 * component configuration files and the search path for the application
103 	 * component configuration files.
104 	 * <p>
105 	 * For example: new JetspeedSerializerImpl("./", "assembly/boot/*.xml",
106 	 * "assembly/*.xml") will establish the current directory as the root,
107 	 * process all xml files in the assembly/boot directory before processing
108 	 * all xml files in the assembly directory itself.
109 	 * 
110 	 * @param appRoot
111 	 *            working directory
112 	 * @param bootConfig
113 	 *            boot (primary) file or files (wildcards are allowed)
114 	 * @param appConfig
115 	 *            application (secondary) file or files (wildcards are allowed)
116 	 */
117 	public JetspeedSerializerSecondaryImpl(String appRoot, String[] bootConfig,
118 			String[] appConfig) throws SerializerException
119 	{
120 		super(appRoot, bootConfig, appConfig);
121 	}
122 
123 	/***
124 	 * reset instruction flags to default settings (all true)
125 	 * 
126 	 */
127 	protected void resetSettings()
128 	{
129 		setSetting(JetspeedSerializer.KEY_PROCESS_USERS, false);
130 		setSetting(JetspeedSerializer.KEY_PROCESS_CAPABILITIES, false);
131 		setSetting(JetspeedSerializer.KEY_PROCESS_PROFILER, false);
132         setSetting(JetspeedSerializer.KEY_PROCESS_PERMISSIONS, false);
133         setSetting(JetspeedSerializer.KEY_PROCESS_USER_PREFERENCES, false);
134 		setSetting(JetspeedSerializer.KEY_OVERWRITE_EXISTING, true);
135 		setSetting(JetspeedSerializer.KEY_BACKUP_BEFORE_PROCESS, true);
136 	}
137 
138 	/***
139 	 * On import, get the basic SnapShot data
140 	 * 
141 	 */
142 	protected void getSnapshotData()
143 	{
144 		logMe("date created : "
145 				+ ((JSSecondaryData) getSnapshot()).getDateCreated());
146 		logMe("software Version : "
147 				+ ((JSSecondaryData) getSnapshot()).getSavedVersion());
148 		logMe("software SUbVersion : "
149 				+ ((JSSecondaryData) getSnapshot()).getSavedSubversion());
150 	}
151 
152 	/***
153 	 * On export, set the basic SnapShot data
154 	 * 
155 	 */
156 	protected void setSnapshotData()
157 	{
158 		super.setSnapshotData();
159 	}
160 
161 	private JSPortlet exportPD(PortletDefinition pd) throws SerializerException
162 	{
163 
164 		try
165 		{
166 			Collection col = entityAccess.getPortletEntities(pd);
167 			if ((col == null) || (col.size() == 0))
168 				return null;
169 			JSPortlet portlet = new JSPortlet();
170 			portlet.setName(pd.getName());
171 			Iterator list = null;
172 			try
173 			{
174 				list = col.iterator();
175 			} catch (Exception e)
176 			{
177 				throw new SerializerException(
178 						SerializerException.GET_EXISTING_OBJECTS
179 								.create(new String[]
180 								{"entityAccess", e.getMessage()}));
181 			}
182 			JSEntities entities = new JSEntities();
183 
184 			while (list.hasNext())
185 			{
186 				MutablePortletEntity entity = (MutablePortletEntity) list
187 						.next();
188 				JSEntity jsEntity = exportEntityPref(entity);
189 				if (jsEntity != null)
190 					entities.add(jsEntity);
191 
192 			}
193 			System.out.println("-----processedAnyEntities for PD="
194 					+ pd.getName());
195 			portlet.setEntities(entities);
196 			return portlet;
197 
198 		} catch (Exception e)
199 		{
200 			throw new SerializerException(
201 					SerializerException.CREATE_SERIALIZED_OBJECT_FAILED
202 							.create(new String[]
203 							{"Entity", e.getMessage()}));
204 		}
205 	}
206 
207 	JSEntity exportEntityPref(MutablePortletEntity entity)
208 	{
209 		JSEntity jsEntity = new JSEntity();
210 		jsEntity.setId(entity.getId().toString());
211 		String rootForEntity = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/"
212 				+ entity.getId();
213 		try
214 		{
215 			if (!(Preferences.userRoot().nodeExists(rootForEntity)))
216 			{
217 				// System.out.println("No preferences exist for entity "+
218 				// entity.getId());
219 				return jsEntity;
220 			}
221 
222 			Preferences prefNode = Preferences.userRoot().node(rootForEntity);
223 			String[] children = prefNode.childrenNames();
224 			if ((children != null) && (children.length > 0))
225 			{
226 				JSEntityPreferences permissions = new JSEntityPreferences();
227 
228 				for (int i = 0; i < children.length; i++)
229 				{
230 					JSEntityPreference permission = processPreferenceNode(
231 							entity, children[i]);
232 					if (permission != null)
233 						permissions.add(permission);
234 				}
235 				System.out.println("processed preferences for entity="
236 						+ entity.getId());
237 				jsEntity.setEntityPreferences(permissions);
238 				return jsEntity;
239 				// processPreferenceNode(entity,prefNode,null);
240 			}
241 			return jsEntity;
242 		} catch (Exception e)
243 		{
244 			e.printStackTrace();
245 			return null;
246 		}
247 
248 	}
249 
250 	JSEntityPreference processPreferenceNode(MutablePortletEntity entity,
251 			String child)
252 	{
253 		String prefNodePath = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/"
254 				+ entity.getId() + "/" + child + "/"
255 				+ PrefsPreference.PORTLET_PREFERENCES_ROOT;
256 		Preferences prefNode = Preferences.userRoot().node(prefNodePath);
257 
258 		if (prefNode == null)
259 			return null;
260 		JSEntityPreference permission = new JSEntityPreference();
261 		permission.setName(child);
262 
263 		try
264 		{
265 			PrefsPreferenceSetImpl preferenceSet = new PrefsPreferenceSetImpl(
266 					prefNode);
267 			if (preferenceSet.size() == 0)
268 				return null;
269 			Iterator it = preferenceSet.iterator();
270 			JSNVPElements v = new JSNVPElements();
271 
272 			while (it.hasNext())
273 			{
274 				Preference pref = (Preference) it.next();
275 				String name = pref.getName();
276 				Iterator ii = pref.getValues();
277 				while (ii.hasNext())
278 				{
279 					Object o = ii.next();
280 					v.add(name, o.toString());
281 				}
282 			}
283 			if (v.size() > 0)
284 			{
285 				permission.setPreferences(v);
286 				return permission;
287 			}
288 			return null;
289 		} catch (Exception e)
290 		{
291 			e.printStackTrace();
292 			return null;
293 
294 		}
295 
296 	}
297 
298 	private JSApplication exportPA(MutablePortletApplication pa)
299 			throws SerializerException
300 	{
301 
302 		JSApplication app = new JSApplication();
303 		System.out.println("--processed PA " + pa.getName() + " with id="
304 				+ pa.getId());
305 		app.setID(pa.getId().toString());
306 		app.setName(pa.getName());
307 		/***
308 		 * while more PAs for each portletDef
309 		 * list:entityMan:getPortletEntity(pd)
310 		 */
311 		PortletDefinitionList portletList = pa.getPortletDefinitionList(); // .get(JetspeedObjectID.createFromString(TEST_PORTLET));
312 		Iterator pi = portletList.iterator();
313 		PortletDefinition pd = null;
314 
315 		JSPortlets portlets = new JSPortlets();
316 		while (pi.hasNext())
317 		{
318 			try
319 			{
320 				pd = (PortletDefinition) pi.next();
321 				JSPortlet p = exportPD(pd);
322 				if (p != null)
323 				{
324 					System.out.println("--processed PA " + pa.getName()
325 							+ " with pd=" + pd.getName());
326 					portlets.add(p);
327 				} else
328 					System.out.println("--processed PA " + pa.getName()
329 							+ " with NULL pd=" + pd.getName());
330 
331 			} catch (Exception e)
332 			{
333 				throw new SerializerException(
334 						SerializerException.CREATE_SERIALIZED_OBJECT_FAILED
335 								.create(new String[]
336 								{"PortletDefinition", e.getMessage()}));
337 			}
338 		}
339 		app.setPortlets(portlets);
340 		return app;
341 	}
342 
343 	private JSApplications exportEntities() throws SerializerException
344 	{
345 		registry = (PortletRegistry) getCM()
346 				.getComponent(
347 						"org.apache.jetspeed.components.portletregistry.PortletRegistry");
348 		if (registry == null)
349 			throw new SerializerException(
350 					SerializerException.COMPONENTMANAGER_DOES_NOT_EXIST
351 							.create("org.apache.jetspeed.components.portletregistry.PortletRegistry"));
352 		Object o = getCM()
353 				.getComponent(
354 						"org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent");
355 		this.entityAccess = (PortletEntityAccessComponent) o;
356 		if (entityAccess == null)
357 			throw new SerializerException(
358 					SerializerException.COMPONENTMANAGER_DOES_NOT_EXIST
359 							.create("org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent"));
360 
361 		JSApplications applications = new JSApplications();
362 
363 		Collection col = registry.getPortletApplications();
364 		if ((col == null) || (col.size() == 0))
365 			return applications;
366 		Iterator list = null;
367 		try
368 		{
369 			list = col.iterator();
370 		} catch (Exception e)
371 		{
372 			throw new SerializerException(
373 					SerializerException.GET_EXISTING_OBJECTS
374 							.create(new String[]
375 							{"registry", e.getMessage()}));
376 		}
377 		while (list.hasNext())
378 		{
379 			try
380 			{
381 				MutablePortletApplication pa = (MutablePortletApplication) list
382 						.next();
383 				// PortletApplicationDefinition pa =
384 				// (PortletApplicationDefinition)list.next();
385 				applications.add(exportPA(pa));
386 			} catch (Exception e)
387 			{
388 				throw new SerializerException(
389 						SerializerException.CREATE_SERIALIZED_OBJECT_FAILED
390 								.create(new String[]
391 								{"PortletApplicationDefinition", e.getMessage()}));
392 			}
393 		}
394 
395 		return applications;
396 	}
397 
398 	/***
399 	 * The workhorse for importing data
400 	 * 
401 	 * @param binding
402 	 *            established XML binding
403 	 * @return
404 	 * @throws SerializerException
405 	 */
406 	protected void processImport() throws SerializerException
407 	{
408 		this.logMe("*********reinstalling data*********");
409 
410 		logMe("creating entities");
411 		importEntities();
412 	}
413 
414 	/***
415 	 * The workhorse for exporting data
416 	 * 
417 	 * @param binding
418 	 *            established XML binding
419 	 * @return
420 	 * @throws SerializerException
421 	 */
422 	protected void processExport(String name, XMLBinding binding)
423 			throws SerializerException
424 	{
425 		this.logMe("*********collecting data*********");
426 		/*** first create the snapshot file */
427 
428 		this.setSnapshot(new JSSecondaryData(name));
429 
430 		setSnapshotData();
431 
432 		JSApplications apps = exportEntities();
433 		((JSSecondaryData) this.getSnapshot()).setApplications(apps);
434 		/***
435 		 * 
436 		 * if (this.getSetting(JetspeedSerializer.KEY_PROCESS_ENTITIES)) {
437 		 * logMe("collecting entities"); exportEntities(); } else
438 		 * logMe("entities skipped");
439 		 * 
440 		 * if (this.getSetting(JetspeedSerializer.KEY_PROCESS_PREFERENCES)) {
441 		 * logMe("collecting preferences"); exportPreferences(); } else
442 		 * logMe("preferences skipped");
443 		 */
444 
445 	}
446 
447 	/***
448 	 * Setup the binding for the different classes, mapping each extracted class
449 	 * to a unique tag name in the XML
450 	 * 
451 	 * @param binding
452 	 */
453 	protected void setupAliases(XMLBinding binding)
454 	{
455 		binding.setAlias(JSApplication.class, "PortletApplication");
456 		binding.setAlias(JSApplications.class, "PortletApplications");
457 		binding.setAlias(JSPortlet.class, "Portlet");
458 		binding.setAlias(JSPortlets.class, "Portlets");
459 		binding.setAlias(JSEntity.class, "Entity");
460 		binding.setAlias(JSEntities.class, "Entities");
461 		binding.setAlias(JSEntityPreference.class, "Principal");
462 		binding.setAlias(JSEntityPreferences.class, "Settings");
463 		binding.setAlias(JSSecondaryData.class, "RegistryData");
464 		binding.setAlias(JSNVPElements.class, "preferences");
465 
466 		binding.setAlias(String.class, "String");
467 		binding.setAlias(Integer.class, "int");
468 		binding.setClassAttribute(null);
469 
470 	}
471 
472 	private void importEntities() throws SerializerException
473 	{
474 		overwrite = getSetting(JetspeedSerializer.KEY_OVERWRITE_EXISTING);
475 
476 		registry = (PortletRegistry) getCM()
477 				.getComponent(
478 						"org.apache.jetspeed.components.portletregistry.PortletRegistry");
479 		if (registry == null)
480 			throw new SerializerException(
481 					SerializerException.COMPONENTMANAGER_DOES_NOT_EXIST
482 							.create("org.apache.jetspeed.components.portletregistry.PortletRegistry"));
483 		Object o = getCM()
484 				.getComponent(
485 						"org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent");
486 		this.entityAccess = (PortletEntityAccessComponent) o;
487 		if (entityAccess == null)
488 			throw new SerializerException(
489 					SerializerException.COMPONENTMANAGER_DOES_NOT_EXIST
490 							.create("org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent"));
491 		
492 		JSApplications applications = ((JSSecondaryData)this.getSnapshot()).getApplications();
493 
494 		if (applications == null)
495 		{
496 			System.out.println("NO DATA!!!!!!");
497 			return;
498 		}
499 		Iterator it = applications.iterator();
500 		while (it.hasNext())
501 		{
502 			JSApplication app = (JSApplication)it.next();
503 			MutablePortletApplication portletApp = registry.getPortletApplication(app.getName());
504 			if (portletApp != null)
505 			{
506 				importPA(app,portletApp);
507 			}
508 		}
509 	}
510 
511 	void importPA(JSApplication app, MutablePortletApplication pa)
512 	throws SerializerException
513 	{
514 
515 		
516 		System.out.println("--processed PA " + pa.getName() + " with id="
517 		+ pa.getId());
518 		/***
519 		 * while more PAs for each portletDef
520 		 * list:entityMan:getPortletEntity(pd)
521 		 */
522 		
523 		Iterator pi = app.getPortlets().iterator();
524 		while (pi.hasNext())
525 		{
526 			JSPortlet portlet = (JSPortlet)pi.next();
527 			PortletDefinition pd  = pa.getPortletDefinitionByName(portlet.getName());
528 			if (pd != null)
529 			{
530 				importPD(portlet,pd); 
531 			}
532 		}
533 	}
534 	
535 	private void importPD(JSPortlet portlet, PortletDefinition pd) throws SerializerException
536 	{
537 
538 		JSEntities entities = portlet.getEntities();
539 		Iterator it = entities.iterator();
540 		while (it.hasNext())
541 		{
542 			JSEntity entity = (JSEntity)it.next();
543 			MutablePortletEntity portletEntity = entityAccess.getPortletEntity(entity.getId());
544 			if (portletEntity == null)
545 			{
546 				portletEntity = entityAccess.newPortletEntityInstance(pd, entity.getId());
547 				try
548 				{
549 					entityAccess.storePortletEntity(portletEntity);
550 				}
551 				catch (Exception e)
552 				{
553 					e.printStackTrace();
554 				}
555 			}
556 			// check preferences
557 			
558 			importEntityPref(entity , portletEntity);
559 		}
560 	}
561 
562 	private void importEntityPref(JSEntity entity , MutablePortletEntity portletEntity)
563 	{
564 
565 		// do I carry any preferences?
566 		JSEntityPreferences preferences = entity.getEntityPreferences();
567 		if ((preferences == null) || (preferences.size() == 0))
568 			return;
569 		
570 		
571 		//since I do have preferences let us make sure we have a root node
572 		
573 		String rootForEntity = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/"
574 				+ portletEntity.getId();
575 		try
576 		{
577 			Preferences.userRoot().node(rootForEntity); // will create it if it doesn't exist
578 			
579 			
580 			Iterator it = preferences.iterator();
581 			while (it.hasNext())
582 			{
583 				JSEntityPreference preference = (JSEntityPreference)it.next();
584 				
585 				// do we have preferences for this one?
586 				importPreferenceNode(preference,portletEntity);
587 			}
588 			
589 		
590 		} catch (Exception e)
591 		{
592 			e.printStackTrace();
593 			return;
594 		}
595 
596 	}
597 
598 	private void importPreferenceNode(JSEntityPreference preference, MutablePortletEntity entity)
599 	{
600 
601 		String child = preference.getName();
602 		
603 		String prefNodePath = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/"
604 				+ entity.getId() + "/" + child + "/"
605 				+ PrefsPreference.PORTLET_PREFERENCES_ROOT;
606 		Preferences prefNode = Preferences.userRoot().node(prefNodePath);
607 
608 		if (prefNode == null)
609 			return ;
610 
611 		JSNVPElements prefList = preference.getPreferences();
612 		try
613 		{
614 			PrefsPreferenceSetImpl preferenceSet = new PrefsPreferenceSetImpl(
615 					prefNode);
616 			
617 			Iterator it = prefList.getMyMap().keySet().iterator();
618 			
619 			while (it.hasNext())
620 			{
621 				String key = (String)it.next();
622 				String value = (String)prefList.getMyMap().get(key);
623 				Preference p = preferenceSet.get(key);
624 				if ((p == null) || (overwrite))
625 				{
626 					
627 					Vector v = new Vector();
628 					v.add(value);
629 					preferenceSet.add(key, v);
630 System.out.println("Entity " + entity.getId() + " updated with preference " + key + "=" + value);					
631 				}
632 			}
633 			preferenceSet.flush();
634 			return;
635 		} catch (Exception e)
636 		{
637 			e.printStackTrace();
638 			return;
639 
640 		}
641 
642 	}
643 	
644 	
645 }