/*
* OneCMDB, an open source configuration management project.
* Copyright 2007, Lokomo Systems AB, and individual contributors
* as indicated by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.onecmdb.core.utils.xml;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.onecmdb.core.IAttribute;
import org.onecmdb.core.ICi;
import org.onecmdb.core.IObjectScope;
import org.onecmdb.core.internal.model.AbstractAttribute;
import org.onecmdb.core.internal.model.ConfigurationItem;
import org.onecmdb.core.utils.bean.AttributeBean;
import org.onecmdb.core.utils.bean.CiBean;
public class BeanCache extends HashMap<Long, CiBean> {
private static BeanCache cache = new BeanCache();
private List<Long> insertOrder = new ArrayList<Long>();
private long misses;
private long hits;
// No limit, can be set by spring to ModelService.
private int maxSize = -1;
public static BeanCache getInstance() {
return(cache);
}
public void invalidate(IObjectScope scope) {
for (ICi ci: scope.getDestroyedICis()) {
remove(ci);
}
for (ICi ci: scope.getModifiedICis()) {
remove(ci);
}
for (ICi ci: scope.getNewICis()) {
remove(ci);
}
}
public void remove(ICi ci) {
if (ci instanceof AbstractAttribute) {
remove(((AbstractAttribute)ci).getOwnerId());
} else {
CiBean cBean = remove(ci.getId().asLong());
if (ci instanceof ConfigurationItem) {
ConfigurationItem cfgItem = (ConfigurationItem)ci;
if (cfgItem.getSourceId() != null) {
remove(cfgItem.getSourceId());
}
if (cfgItem.getTargetId() != null) {
remove(cfgItem.getTargetId());
}
}
handleAliasChange(ci, cBean);
}
}
private void handleAliasChange(ICi ci, CiBean cBean) {
if (cBean == null || ci == null) {
return;
}
String alias = ci.getAlias();
if (alias == null) {
return;
}
String oldAlias = cBean.getAlias();
if (oldAlias == null) {
return;
}
if (!alias.equals(oldAlias)) {
// Clean up if alias has changed.
List<Long> removeIds = new ArrayList<Long>();
for (CiBean bean : values()) {
if (!bean.isTemplate()) {
continue;
}
for (AttributeBean aBean : bean.getAttributes()) {
if (oldAlias.equals(aBean.getType())) {
removeIds.add(bean.getId());
}
if (oldAlias.equals(aBean.getRefType())) {
removeIds.add(bean.getId());
}
}
}
for (Long id : removeIds) {
remove(id);
}
}
}
public CiBean get(ICi ci) {
CiBean bean = get(ci.getId().asLong());
if (bean == null) {
misses++;
} else {
// Need to copy the bean so we don't destroy entries.
// Validate lastModified.
bean = bean.copy();
hits++;
}
return(bean);
}
private boolean isModified(Date lastModified, Date lastModified2) {
if (lastModified == null) {
return(true);
}
if (lastModified2 == null) {
return(true);
}
if (lastModified.compareTo(lastModified2) != 0) {
return(true);
}
return(false);
}
public void add(ICi ci, CiBean bean) {
put(ci.getId().asLong(), bean);
insertOrder.add(ci.getId().asLong());
// Check size...
if (this.maxSize >= 0) {
if (insertOrder.size() > this.maxSize) {
Long id = insertOrder.remove(insertOrder.size()-1);
remove(id);
}
}
}
public String getStatistics() {
return("BeanCache: Size=" + size() + ", hits=" + hits + ", misses=" + misses);
}
public void setMaxSize(int size) {
this.maxSize = size;
}
}