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_USER_PREFERENCES, true);
133 		setSetting(JetspeedSerializer.KEY_OVERWRITE_EXISTING, true);
134 		setSetting(JetspeedSerializer.KEY_BACKUP_BEFORE_PROCESS, true);
135 	}
136 
137 	/***
138 	 * On import, get the basic SnapShot data
139 	 * 
140 	 */
141 	protected void getSnapshotData()
142 	{
143 		logMe("date created : "
144 				+ ((JSSecondaryData) getSnapshot()).getDateCreated());
145 		logMe("software Version : "
146 				+ ((JSSecondaryData) getSnapshot()).getSavedVersion());
147 		logMe("software SUbVersion : "
148 				+ ((JSSecondaryData) getSnapshot()).getSavedSubversion());
149 	}
150 
151 	/***
152 	 * On export, set the basic SnapShot data
153 	 * 
154 	 */
155 	protected void setSnapshotData()
156 	{
157 		super.setSnapshotData();
158 	}
159 
160 	private JSPortlet exportPD(PortletDefinition pd) throws SerializerException
161 	{
162 
163 		try
164 		{
165 			Collection col = entityAccess.getPortletEntities(pd);
166 			if ((col == null) || (col.size() == 0))
167 				return null;
168 			JSPortlet portlet = new JSPortlet();
169 			portlet.setName(pd.getName());
170 			Iterator list = null;
171 			try
172 			{
173 				list = col.iterator();
174 			} catch (Exception e)
175 			{
176 				throw new SerializerException(
177 						SerializerException.GET_EXISTING_OBJECTS
178 								.create(new String[]
179 								{"entityAccess", e.getMessage()}));
180 			}
181 			JSEntities entities = new JSEntities();
182 
183 			while (list.hasNext())
184 			{
185 				MutablePortletEntity entity = (MutablePortletEntity) list
186 						.next();
187 				JSEntity jsEntity = exportEntityPref(entity);
188 				if (jsEntity != null)
189 					entities.add(jsEntity);
190 
191 			}
192 			System.out.println("-----processedAnyEntities for PD="
193 					+ pd.getName());
194 			portlet.setEntities(entities);
195 			return portlet;
196 
197 		} catch (Exception e)
198 		{
199 			throw new SerializerException(
200 					SerializerException.CREATE_SERIALIZED_OBJECT_FAILED
201 							.create(new String[]
202 							{"Entity", e.getMessage()}));
203 		}
204 	}
205 
206 	JSEntity exportEntityPref(MutablePortletEntity entity)
207 	{
208 		JSEntity jsEntity = new JSEntity();
209 		jsEntity.setId(entity.getId().toString());
210 		String rootForEntity = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/"
211 				+ entity.getId();
212 		try
213 		{
214 			if (!(Preferences.userRoot().nodeExists(rootForEntity)))
215 			{
216 				// System.out.println("No preferences exist for entity "+
217 				// entity.getId());
218 				return jsEntity;
219 			}
220 
221 			Preferences prefNode = Preferences.userRoot().node(rootForEntity);
222 			String[] children = prefNode.childrenNames();
223 			if ((children != null) && (children.length > 0))
224 			{
225 				JSEntityPreferences permissions = new JSEntityPreferences();
226 
227 				for (int i = 0; i < children.length; i++)
228 				{
229 					JSEntityPreference permission = processPreferenceNode(
230 							entity, children[i]);
231 					if (permission != null)
232 						permissions.add(permission);
233 				}
234 				System.out.println("processed preferences for entity="
235 						+ entity.getId());
236 				jsEntity.setEntityPreferences(permissions);
237 				return jsEntity;
238 				// processPreferenceNode(entity,prefNode,null);
239 			}
240 			return jsEntity;
241 		} catch (Exception e)
242 		{
243 			e.printStackTrace();
244 			return null;
245 		}
246 
247 	}
248 
249 	JSEntityPreference processPreferenceNode(MutablePortletEntity entity,
250 			String child)
251 	{
252 		String prefNodePath = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/"
253 				+ entity.getId() + "/" + child + "/"
254 				+ PrefsPreference.PORTLET_PREFERENCES_ROOT;
255 		Preferences prefNode = Preferences.userRoot().node(prefNodePath);
256 
257 		if (prefNode == null)
258 			return null;
259 		JSEntityPreference permission = new JSEntityPreference();
260 		permission.setName(child);
261 
262 		try
263 		{
264 			PrefsPreferenceSetImpl preferenceSet = new PrefsPreferenceSetImpl(
265 					prefNode);
266 			if (preferenceSet.size() == 0)
267 				return null;
268 			Iterator it = preferenceSet.iterator();
269 			JSNVPElements v = new JSNVPElements();
270 
271 			while (it.hasNext())
272 			{
273 				Preference pref = (Preference) it.next();
274 				String name = pref.getName();
275 				Iterator ii = pref.getValues();
276 				while (ii.hasNext())
277 				{
278 					Object o = ii.next();
279 					v.add(name, o.toString());
280 				}
281 			}
282 			if (v.size() > 0)
283 			{
284 				permission.setPreferences(v);
285 				return permission;
286 			}
287 			return null;
288 		} catch (Exception e)
289 		{
290 			e.printStackTrace();
291 			return null;
292 
293 		}
294 
295 	}
296 
297 	private JSApplication exportPA(MutablePortletApplication pa)
298 			throws SerializerException
299 	{
300 
301 		JSApplication app = new JSApplication();
302 		System.out.println("--processed PA " + pa.getName() + " with id="
303 				+ pa.getId());
304 		app.setID(pa.getId().toString());
305 		app.setName(pa.getName());
306 		/***
307 		 * while more PAs for each portletDef
308 		 * list:entityMan:getPortletEntity(pd)
309 		 */
310 		PortletDefinitionList portletList = pa.getPortletDefinitionList(); // .get(JetspeedObjectID.createFromString(TEST_PORTLET));
311 		Iterator pi = portletList.iterator();
312 		PortletDefinition pd = null;
313 
314 		JSPortlets portlets = new JSPortlets();
315 		while (pi.hasNext())
316 		{
317 			try
318 			{
319 				pd = (PortletDefinition) pi.next();
320 				JSPortlet p = exportPD(pd);
321 				if (p != null)
322 				{
323 					System.out.println("--processed PA " + pa.getName()
324 							+ " with pd=" + pd.getName());
325 					portlets.add(p);
326 				} else
327 					System.out.println("--processed PA " + pa.getName()
328 							+ " with NULL pd=" + pd.getName());
329 
330 			} catch (Exception e)
331 			{
332 				throw new SerializerException(
333 						SerializerException.CREATE_SERIALIZED_OBJECT_FAILED
334 								.create(new String[]
335 								{"PortletDefinition", e.getMessage()}));
336 			}
337 		}
338 		app.setPortlets(portlets);
339 		return app;
340 	}
341 
342 	private JSApplications exportEntities() throws SerializerException
343 	{
344 		registry = (PortletRegistry) getCM()
345 				.getComponent(
346 						"org.apache.jetspeed.components.portletregistry.PortletRegistry");
347 		if (registry == null)
348 			throw new SerializerException(
349 					SerializerException.COMPONENTMANAGER_DOES_NOT_EXIST
350 							.create("org.apache.jetspeed.components.portletregistry.PortletRegistry"));
351 		Object o = getCM()
352 				.getComponent(
353 						"org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent");
354 		this.entityAccess = (PortletEntityAccessComponent) o;
355 		if (entityAccess == null)
356 			throw new SerializerException(
357 					SerializerException.COMPONENTMANAGER_DOES_NOT_EXIST
358 							.create("org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent"));
359 
360 		JSApplications applications = new JSApplications();
361 
362 		Collection col = registry.getPortletApplications();
363 		if ((col == null) || (col.size() == 0))
364 			return applications;
365 		Iterator list = null;
366 		try
367 		{
368 			list = col.iterator();
369 		} catch (Exception e)
370 		{
371 			throw new SerializerException(
372 					SerializerException.GET_EXISTING_OBJECTS
373 							.create(new String[]
374 							{"registry", e.getMessage()}));
375 		}
376 		while (list.hasNext())
377 		{
378 			try
379 			{
380 				MutablePortletApplication pa = (MutablePortletApplication) list
381 						.next();
382 				// PortletApplicationDefinition pa =
383 				// (PortletApplicationDefinition)list.next();
384 				applications.add(exportPA(pa));
385 			} catch (Exception e)
386 			{
387 				throw new SerializerException(
388 						SerializerException.CREATE_SERIALIZED_OBJECT_FAILED
389 								.create(new String[]
390 								{"PortletApplicationDefinition", e.getMessage()}));
391 			}
392 		}
393 
394 		return applications;
395 	}
396 
397 	/***
398 	 * The workhorse for importing data
399 	 * 
400 	 * @param binding
401 	 *            established XML binding
402 	 * @return
403 	 * @throws SerializerException
404 	 */
405 	protected void processImport() throws SerializerException
406 	{
407 		this.logMe("*********reinstalling data*********");
408 
409 		logMe("creating entities");
410 		importEntities();
411 	}
412 
413 	/***
414 	 * The workhorse for exporting data
415 	 * 
416 	 * @param binding
417 	 *            established XML binding
418 	 * @return
419 	 * @throws SerializerException
420 	 */
421 	protected void processExport(String name, XMLBinding binding)
422 			throws SerializerException
423 	{
424 		this.logMe("*********collecting data*********");
425 		/*** first create the snapshot file */
426 
427 		this.setSnapshot(new JSSecondaryData(name));
428 
429 		setSnapshotData();
430 
431 		JSApplications apps = exportEntities();
432 		((JSSecondaryData) this.getSnapshot()).setApplications(apps);
433 		/***
434 		 * 
435 		 * if (this.getSetting(JetspeedSerializer.KEY_PROCESS_ENTITIES)) {
436 		 * logMe("collecting entities"); exportEntities(); } else
437 		 * logMe("entities skipped");
438 		 * 
439 		 * if (this.getSetting(JetspeedSerializer.KEY_PROCESS_PREFERENCES)) {
440 		 * logMe("collecting preferences"); exportPreferences(); } else
441 		 * logMe("preferences skipped");
442 		 */
443 
444 	}
445 
446 	/***
447 	 * Setup the binding for the different classes, mapping each extracted class
448 	 * to a unique tag name in the XML
449 	 * 
450 	 * @param binding
451 	 */
452 	protected void setupAliases(XMLBinding binding)
453 	{
454 		binding.setAlias(JSApplication.class, "PortletApplication");
455 		binding.setAlias(JSApplications.class, "PortletApplications");
456 		binding.setAlias(JSPortlet.class, "Portlet");
457 		binding.setAlias(JSPortlets.class, "Portlets");
458 		binding.setAlias(JSEntity.class, "Entity");
459 		binding.setAlias(JSEntities.class, "Entities");
460 		binding.setAlias(JSEntityPreference.class, "Principal");
461 		binding.setAlias(JSEntityPreferences.class, "Settings");
462 		binding.setAlias(JSSecondaryData.class, "RegistryData");
463 		binding.setAlias(JSNVPElements.class, "preferences");
464 
465 		binding.setAlias(String.class, "String");
466 		binding.setAlias(Integer.class, "int");
467 		binding.setClassAttribute(null);
468 
469 	}
470 
471 	private void importEntities() throws SerializerException
472 	{
473 		overwrite = getSetting(JetspeedSerializer.KEY_OVERWRITE_EXISTING);
474 
475 		registry = (PortletRegistry) getCM()
476 				.getComponent(
477 						"org.apache.jetspeed.components.portletregistry.PortletRegistry");
478 		if (registry == null)
479 			throw new SerializerException(
480 					SerializerException.COMPONENTMANAGER_DOES_NOT_EXIST
481 							.create("org.apache.jetspeed.components.portletregistry.PortletRegistry"));
482 		Object o = getCM()
483 				.getComponent(
484 						"org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent");
485 		this.entityAccess = (PortletEntityAccessComponent) o;
486 		if (entityAccess == null)
487 			throw new SerializerException(
488 					SerializerException.COMPONENTMANAGER_DOES_NOT_EXIST
489 							.create("org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent"));
490 		
491 		JSApplications applications = ((JSSecondaryData)this.getSnapshot()).getApplications();
492 
493 		if (applications == null)
494 		{
495 			System.out.println("NO DATA!!!!!!");
496 			return;
497 		}
498 		Iterator it = applications.iterator();
499 		while (it.hasNext())
500 		{
501 			JSApplication app = (JSApplication)it.next();
502 			MutablePortletApplication portletApp = registry.getPortletApplication(app.getName());
503 			if (portletApp != null)
504 			{
505 				importPA(app,portletApp);
506 			}
507 		}
508 	}
509 
510 	void importPA(JSApplication app, MutablePortletApplication pa)
511 	throws SerializerException
512 	{
513 
514 		
515 		System.out.println("--processed PA " + pa.getName() + " with id="
516 		+ pa.getId());
517 		/***
518 		 * while more PAs for each portletDef
519 		 * list:entityMan:getPortletEntity(pd)
520 		 */
521 		
522 		Iterator pi = app.getPortlets().iterator();
523 		while (pi.hasNext())
524 		{
525 			JSPortlet portlet = (JSPortlet)pi.next();
526 			PortletDefinition pd  = pa.getPortletDefinitionByName(portlet.getName());
527 			if (pd != null)
528 			{
529 				importPD(portlet,pd); 
530 			}
531 		}
532 	}
533 	
534 	private void importPD(JSPortlet portlet, PortletDefinition pd) throws SerializerException
535 	{
536 
537 		JSEntities entities = portlet.getEntities();
538 		Iterator it = entities.iterator();
539 		while (it.hasNext())
540 		{
541 			JSEntity entity = (JSEntity)it.next();
542 			MutablePortletEntity portletEntity = entityAccess.getPortletEntity(entity.getId());
543 			if (portletEntity == null)
544 			{
545 				portletEntity = entityAccess.newPortletEntityInstance(pd, entity.getId());
546 				try
547 				{
548 					entityAccess.storePortletEntity(portletEntity);
549 				}
550 				catch (Exception e)
551 				{
552 					e.printStackTrace();
553 				}
554 			}
555 			// check preferences
556 			
557 			importEntityPref(entity , portletEntity);
558 		}
559 	}
560 
561 	private void importEntityPref(JSEntity entity , MutablePortletEntity portletEntity)
562 	{
563 
564 		// do I carry any preferences?
565 		JSEntityPreferences preferences = entity.getEntityPreferences();
566 		if ((preferences == null) || (preferences.size() == 0))
567 			return;
568 		
569 		
570 		//since I do have preferences let us make sure we have a root node
571 		
572 		String rootForEntity = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/"
573 				+ portletEntity.getId();
574 		try
575 		{
576 			Preferences.userRoot().node(rootForEntity); // will create it if it doesn't exist
577 			
578 			
579 			Iterator it = preferences.iterator();
580 			while (it.hasNext())
581 			{
582 				JSEntityPreference preference = (JSEntityPreference)it.next();
583 				
584 				// do we have preferences for this one?
585 				importPreferenceNode(preference,portletEntity);
586 			}
587 			
588 		
589 		} catch (Exception e)
590 		{
591 			e.printStackTrace();
592 			return;
593 		}
594 
595 	}
596 
597 	private void importPreferenceNode(JSEntityPreference preference, MutablePortletEntity entity)
598 	{
599 
600 		String child = preference.getName();
601 		
602 		String prefNodePath = MutablePortletEntity.PORTLET_ENTITY_ROOT + "/"
603 				+ entity.getId() + "/" + child + "/"
604 				+ PrefsPreference.PORTLET_PREFERENCES_ROOT;
605 		Preferences prefNode = Preferences.userRoot().node(prefNodePath);
606 
607 		if (prefNode == null)
608 			return ;
609 
610 		JSNVPElements prefList = preference.getPreferences();
611 		try
612 		{
613 			PrefsPreferenceSetImpl preferenceSet = new PrefsPreferenceSetImpl(
614 					prefNode);
615 			
616 			Iterator it = prefList.getMyMap().keySet().iterator();
617 			
618 			while (it.hasNext())
619 			{
620 				String key = (String)it.next();
621 				String value = (String)prefList.getMyMap().get(key);
622 				Preference p = preferenceSet.get(key);
623 				if ((p == null) || (overwrite))
624 				{
625 					
626 					Vector v = new Vector();
627 					v.add(value);
628 					preferenceSet.add(key, v);
629 System.out.println("Entity " + entity.getId() + " updated with preference " + key + "=" + value);					
630 				}
631 			}
632 			preferenceSet.flush();
633 			return;
634 		} catch (Exception e)
635 		{
636 			e.printStackTrace();
637 			return;
638 
639 		}
640 
641 	}
642 	
643 	
644 }