001 /**
002 * hammurapi-rules @mesopotamia.version@
003 * Hammurapi rules engine.
004 * Copyright (C) 2005 Hammurapi Group
005 *
006 * This program is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 2 of the License, or (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with this library; if not, write to the Free Software
018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019 *
020 * URL: http://http://www.hammurapi.biz
021 * e-Mail: support@hammurapi.biz
022 */
023 package biz.hammurapi.rules;
024
025 import java.io.Serializable;
026 import java.util.ArrayList;
027 import java.util.Collection;
028 import java.util.HashMap;
029 import java.util.Iterator;
030 import java.util.LinkedHashMap;
031 import java.util.Map;
032
033 import javax.rules.Handle;
034
035 import biz.hammurapi.config.Component;
036 import biz.hammurapi.config.ComponentBase;
037 import biz.hammurapi.config.ConfigurationException;
038
039 /**
040 * Handle manager implementation which keeps handles in memory.
041 * Objects are compared by identity, not by eqals().
042 * @author Pavel Vlasov
043 * @version ${Revision}
044 */
045 public class IdentityHandleManager extends ComponentBase implements HandleManager, Component {
046
047 private Map handleMap;
048
049 private String storageReference;
050
051 /**
052 * Path to object storage.
053 * @param storageReference
054 */
055 public void setStorageReference(String storageReference) {
056 this.storageReference = storageReference;
057 }
058
059
060 private static class HandleImpl implements Handle, Serializable {
061 private static final long serialVersionUID = -6198273232968377370L;
062 private Object master;
063
064
065 HandleImpl(Object master) {
066 this.master=master;
067 }
068
069 public boolean equals(Object obj) {
070 return obj instanceof HandleImpl && master==((HandleImpl) obj).master;
071 }
072
073 public int hashCode() {
074 return master==null ? 0 : master.hashCode();
075 }
076
077 public String toString() {
078 return getClass().getName() + " -> " + master;
079 }
080 }
081
082 synchronized public Handle addObject(Object object) {
083 Handle newHandle=new HandleImpl(object);
084 Handle existingHandle=(Handle) handleMap.get(newHandle);
085 if (existingHandle==null) {
086 handleMap.put(newHandle, newHandle);
087 return newHandle;
088 }
089
090 return existingHandle;
091 }
092
093 synchronized public Object getObject(Handle handle) {
094 if (handle instanceof HandleImpl) {
095 return ((HandleImpl) handle).master;
096 }
097
098 throw new IllegalArgumentException("Foreign handle: "+handle);
099 }
100
101 public Collection getObjects() {
102 ArrayList ret=new ArrayList();
103 Iterator it=handleMap.keySet().iterator();
104 while (it.hasNext()) {
105 ret.add(((HandleImpl) it.next()).master);
106 }
107 return ret;
108 }
109
110 public Collection getHandles() {
111 return handleMap.keySet();
112 }
113
114 synchronized public void remove(Handle handle) {
115 handleMap.remove(handle);
116 }
117
118 public boolean contains(Handle handle) {
119 return handleMap.containsKey(handle);
120 }
121
122 synchronized public void rebind(Handle handle, Object object) {
123 if (handle instanceof HandleImpl) {
124 handleMap.remove(handle);
125 ((HandleImpl) handle).master=object;
126 handleMap.put(handle, handle);
127 } else {
128 throw new IllegalArgumentException("Foreign handle: "+handle);
129 }
130 }
131
132 public void remove(Object obj) {
133 handleMap.remove(new HandleImpl(obj));
134 }
135
136 public synchronized void clear() {
137 handleMap.clear();
138 }
139
140 public void start() throws ConfigurationException {
141 if (storageReference==null) {
142 handleMap=new LinkedHashMap();
143 } else {
144 handleMap = (Map) ((ObjectStorage) get(storageReference)).get("handle-manager");
145 if (handleMap==null) {
146 handleMap=new HashMap();
147 ((ObjectStorage) get(storageReference)).put("handle-manager", handleMap);
148 }
149 }
150 }
151
152 public void stop() throws ConfigurationException {
153 // Nothing
154 }
155
156 public synchronized boolean isNegatedBy(Negator negator) {
157 Iterator it=handleMap.keySet().iterator();
158 while (it.hasNext()) {
159 HandleImpl handle=(HandleImpl) it.next();
160 if (Conclusion.object2Negator(handle.master, negator)) {
161 it.remove();
162 }
163 }
164
165 return false;
166 }
167 }