/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* !#
*/
package net.ontopia.topicmaps.impl.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.ontopia.infoset.core.LocatorIF;
import net.ontopia.topicmaps.core.TMObjectIF;
import net.ontopia.topicmaps.core.TopicMapIF;
import net.ontopia.utils.CompactHashSet;
import net.ontopia.utils.OntopiaRuntimeException;
/**
* INTERNAL: Default implementation of the TMRevitalizerIF interface.
*/
public class TMRevitalizer implements TMRevitalizerIF {
protected TopicMapIF topicmap;
protected Map processed;
public TMRevitalizer(TopicMapIF topicmap) {
this.topicmap = topicmap;
this.processed = new IdentityHashMap();
}
public Object revitalize(Object o) {
// no need to revitalize null
if (o == null) return null;
// check to see if object has already been processed
if (processed.containsKey(o))
return processed.get(o);
if (o instanceof TMRevitalizableIF) {
processed.put(o, o);
((TMRevitalizableIF)o).revitalize(this);
return o;
} else if (o instanceof TMObjectIF) {
Object x = revitalize((TMObjectIF)o);
processed.put(o, x);
return x;
} else if (o instanceof List) {
processed.put(o, null);
Object x = revitalize((List)o);
processed.put(o, x);
return x;
} else if (o instanceof Set) {
processed.put(o, null);
Object x = revitalize((Set)o);
processed.put(o, x);
return x;
} else if (o instanceof Collection) {
processed.put(o, null);
Object x = revitalize((Collection)o);
processed.put(o, x);
return x;
} else if (o instanceof Map) {
processed.put(o, null);
Object x = revitalize((Map)o);
processed.put(o, x);
return x;
} else if (o.getClass().isPrimitive() ||
o instanceof String ||
o instanceof LocatorIF ||
o instanceof Boolean ||
o instanceof Integer) {
return o;
} else {
throw new OntopiaRuntimeException("Cannot revitalize object " + o);
}
}
// -- private methods
private TMObjectIF revitalize(TMObjectIF o) {
TMObjectIF revitalized = topicmap.getObjectById(o.getObjectId());
// ISSUE: what if new object have different type than old
// object. this can actually happen if the topic map is reloaded
// from file in the meantime.
if (revitalized == null)
throw new OntopiaRuntimeException("Object " + o + " could not be revitalized because it can no longer be found in the topic map.");
else
return revitalized;
}
private Object[] revitalize(Object[] a) {
Object[] result = (Object[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), a.length);
for (int i=0; i < a.length; i++) {
result[i] = revitalize(a[i]);
}
return result;
}
private Collection revitalize(Collection c) {
Collection result = new ArrayList(c.size());
Iterator iter = c.iterator();
while (iter.hasNext()) {
Object o = iter.next();
result.add(revitalize(o));
}
return result;
}
private List revitalize(List c) {
int size = c.size();
List result = new ArrayList(size);
for (int i=0; i < size; i++) {
result.add(revitalize(c.get(i)));
}
return result;
}
private Set revitalize(Set c) {
Set result = new CompactHashSet(c.size());
Iterator iter = c.iterator();
while (iter.hasNext()) {
Object o = iter.next();
result.add(revitalize(o));
}
return result;
}
private Map revitalize(Map m) {
Map result = new HashMap(m.size());
Iterator i = m.keySet().iterator();
while (i.hasNext()) {
Object k = i.next();
result.put(revitalize(k), revitalize(m.get(k)));
}
return result;
}
}