/*
* component: "openEHR Java Reference Implementation"
* description: "Class RMUtil"
* keywords: "rm-skeleton"
*
* author: "Rong Chen <rong.acode@gmail.com>"
* copyright: "Copyright (c) 2009,2010 Cambio Healthcare Systems, Sweden"
* license: "See notice at bottom of class"
*
* file: "$URL$"
* revision: "$LastChangedRevision$"
* last_change: "$LastChangedDate$"
*/
package org.openehr.rm.util;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.openehr.rm.composition.Composition;
import org.openehr.rm.composition.content.ContentItem;
import org.openehr.rm.composition.content.entry.Action;
import org.openehr.rm.composition.content.entry.Activity;
import org.openehr.rm.composition.content.entry.AdminEntry;
import org.openehr.rm.composition.content.entry.Entry;
import org.openehr.rm.composition.content.entry.Evaluation;
import org.openehr.rm.composition.content.entry.Instruction;
import org.openehr.rm.composition.content.entry.Observation;
import org.openehr.rm.composition.content.navigation.Section;
import org.openehr.rm.datastructure.history.Event;
import org.openehr.rm.datastructure.history.History;
import org.openehr.rm.datastructure.itemstructure.ItemList;
import org.openehr.rm.datastructure.itemstructure.ItemStructure;
import org.openehr.rm.datastructure.itemstructure.ItemTree;
import org.openehr.schemas.v1.ACTIVITY;
/**
* Support class that provide various utility functions
*
* TODO
* some of these functions could end up in RM classes themselves
*
* @author rong.chen
*
*/
public class RMUtil {
/**
* Clears away unnecessary RM structure in given composition
*
* The following structures are purged
* 1. section with empty list of items
* 2. entry with empty items as data or other key attributes
*
* TODO
* only entry type Observation is expected for now
*
* @param composition
*/
public static void purge(Composition composition) {
log.debug("Composition.purge() started..");
List<ContentItem> items = composition.getContent();
for(Iterator<ContentItem> it = items.iterator(); it.hasNext();) {
ContentItem item = it.next();
if(isEmpty(item)) {
it.remove();
log.debug("item of class " + item.getClass() + ", removed..");
} else if(item instanceof Section) {
Section section = (Section) item;
purge(section);
}
}
log.debug("Composition.purge() finished..");
}
/**
* Purges the given section. Recursive function.
*
*
* @param section
*/
public static void purge(Section section) {
log.debug("Section.purge() started.. ");
List<ContentItem> items = section.getItems();
for(Iterator<ContentItem> it = items.iterator(); it.hasNext();) {
ContentItem item = it.next();
if(isEmpty(item)) {
it.remove();
log.debug("item of class " + item.getClass() + ", removed..");
} else if(item instanceof Section) {
Section subsection = (Section) item;
purge(subsection);
}
}
log.debug("Section.purge() finished.. ");
}
private static boolean isEmpty(Section section) {
List<ContentItem> items = section.getItems();
if(items.isEmpty()) {
return true;
}
for(Iterator<ContentItem> it = items.iterator(); it.hasNext();) {
ContentItem item = it.next();
if( ! isEmpty(item)) {
return false;
}
}
return true;
}
private static boolean isEmpty(ContentItem item) {
if(item instanceof Section) {
return isEmpty((Section) item);
} else {
return isEmpty((Entry) item);
}
}
private static boolean isEmpty(Entry entry) {
if(entry instanceof Observation) {
Observation obs = (Observation) entry;
return isEmpty(obs.getData());
} else if(entry instanceof Evaluation) {
Evaluation eval = (Evaluation) entry;
return isEmpty(eval.getData());
} else if(entry instanceof Instruction) {
Instruction intr = (Instruction) entry;
List<Activity> activities = intr.getActivities();
if(activities.isEmpty()) {
return true;
}
for(Iterator<Activity> it = activities.iterator(); it.hasNext();) {
Activity activity = it.next();
if( ! isEmpty(activity.getDescription())) {
return false;
}
}
return true;
} else if(entry instanceof Action) {
Action action = (Action) entry;
return isEmpty(action.getDescription());
} else if(entry instanceof AdminEntry) {
AdminEntry admin = (AdminEntry) entry;
return isEmpty(admin.getData());
} else {
throw new UnsupportedOperationException("unsupported entry type");
}
}
private static boolean isEmpty(History<? extends ItemStructure> history) {
if(history.getEvents().isEmpty()) {
return true;
}
for(Iterator it = history.getEvents().iterator(); it.hasNext();) {
Event event = (Event) it.next();
if( ! isEmpty(event.getData())) {
return false;
}
}
return true;
}
private static boolean isEmpty(ItemStructure structure) {
if(structure instanceof ItemList) {
ItemList list = (ItemList) structure;
return list.getItems().isEmpty();
} else if(structure instanceof ItemTree) {
ItemTree tree = (ItemTree) structure;
return tree.getItems().isEmpty();
} else {
// TODO more types
throw new UnsupportedOperationException();
}
}
private static final Logger log = Logger.getLogger(RMUtil.class);
}
/*
* ***** BEGIN LICENSE BLOCK ***** Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the 'License'); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an 'AS IS' basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* The Original Code is RMUtil.java
*
* The Initial Developer of the Original Code is Rong Chen. Portions created by
* the Initial Developer are Copyright (C) 2009-2010 the Initial Developer. All
* Rights Reserved.
*
* Contributor(s):
*
* Software distributed under the License is distributed on an 'AS IS' basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
*
* ***** END LICENSE BLOCK *****
*/