001: /*
002: * $Id: org.eclipse.jdt.ui.prefs 5004 2006-03-17 20:47:08 -0800 (Fri, 17 Mar
003: * 2006) eelco12 $ $Revision: 5004 $ $Date: 2006-03-17 20:47:08 -0800 (Fri, 17
004: * Mar 2006) $
005: *
006: * ==============================================================================
007: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
008: * use this file except in compliance with the License. You may obtain a copy of
009: * the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
015: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
016: * License for the specific language governing permissions and limitations under
017: * the License.
018: */
019: package wicket.protocol.http.request.urlcompressing;
020:
021: import java.io.IOException;
022: import java.io.Serializable;
023: import java.lang.ref.ReferenceQueue;
024: import java.lang.ref.WeakReference;
025: import java.util.Iterator;
026:
027: import wicket.Component;
028: import wicket.request.compound.CompoundRequestCycleProcessor;
029: import wicket.util.collections.IntHashMap;
030: import wicket.util.collections.IntHashMap.Entry;
031:
032: /**
033: * This class generates UID for Component/Interface combinations when used in
034: * conjunction with {@link WebURLCompressingCodingStrategy} and
035: * {@link WebURLCompressingTargetResolverStrategy}
036: *
037: * To use the 2 strategies you have to create your own
038: * {@link CompoundRequestCycleProcessor} in your
039: * application's newRequestCycleProcessor() method, which should be overridden
040: * and implemented like this:
041: *
042: * <pre>
043: * protected IRequestCycleProcessor newRequestCycleProcessor()
044: * {
045: * return new CompoundRequestCycleProcessor(new WebURLCompressingCodingStrategy(),
046: * new WebURLCompressingTargetResolverStrategy(), null, null, null);
047: * }
048: * </pre>
049: *
050: * @since 1.2
051: *
052: * @see WebURLCompressingCodingStrategy
053: * @see WebURLCompressingTargetResolverStrategy
054: *
055: * @author jcompagner
056: */
057: public class URLCompressor implements Serializable {
058: private static final long serialVersionUID = 1L;
059:
060: private transient ReferenceQueue queue = new ReferenceQueue();
061:
062: private transient IntHashMap directComponentRefs = new IntHashMap(); // uid->component/interface
063:
064: private int uid = 1;
065:
066: private void readObject(java.io.ObjectInputStream s)
067: throws IOException, ClassNotFoundException {
068: s.defaultReadObject();
069:
070: int size = s.readInt();
071: queue = new ReferenceQueue();
072: directComponentRefs = new IntHashMap((int) (size * 1.25));
073:
074: while (--size >= 0) {
075: int uid = s.readInt();
076: Component component = (Component) s.readObject();
077: String interfaceName = s.readUTF();
078:
079: IntKeyWeakReference ref = new IntKeyWeakReference(uid,
080: component, queue);
081: directComponentRefs.put(uid, new ComponentAndInterface(ref,
082: interfaceName));
083: }
084:
085: }
086:
087: private void writeObject(java.io.ObjectOutputStream s)
088: throws IOException {
089: IntKeyWeakReference ref = null;
090: while ((ref = (IntKeyWeakReference) queue.poll()) != null) {
091: directComponentRefs.remove(ref.uid);
092: }
093:
094: s.defaultWriteObject();
095:
096: s.writeInt(directComponentRefs.size());
097:
098: Iterator it = directComponentRefs.entrySet().iterator();
099: while (it.hasNext()) {
100: IntHashMap.Entry entry = (Entry) it.next();
101:
102: s.writeInt(entry.getKey());
103: ComponentAndInterface cai = (ComponentAndInterface) entry
104: .getValue();
105: s.writeObject(cai.getComponent());
106: s.writeUTF(cai.getInterfaceName());
107: }
108: }
109:
110: /**
111: * @return the next uid for this url compressor
112: */
113: public int getNewUID() {
114: return uid++;
115: }
116:
117: /**
118: * Returns a uid for the combination component and the to call interface.
119: * Will return the same uid if it was already called for this specific
120: * combination.
121: *
122: * @param component
123: * The Component
124: * @param interfaceName
125: * The interface name
126: * @return int The uid for the component/interfaceName combination
127: */
128: public int getUIDForComponentAndInterface(Component component,
129: String interfaceName) {
130: int uid = 0;
131: Iterator it = directComponentRefs.entrySet().iterator();
132: while (it.hasNext()) {
133: IntHashMap.Entry entry = (IntHashMap.Entry) it.next();
134: ComponentAndInterface cai = (ComponentAndInterface) entry
135: .getValue();
136: if (cai.getInterfaceName().equals(interfaceName)
137: && cai.getComponent() == component) {
138: uid = entry.getKey();
139: break;
140: }
141: }
142: if (uid == 0) {
143: uid = getNewUID();
144: IntKeyWeakReference ref = new IntKeyWeakReference(uid,
145: component, queue);
146: directComponentRefs.put(uid, new ComponentAndInterface(ref,
147: interfaceName));
148: }
149: return uid;
150: }
151:
152: /**
153: * Gets the combination
154: *
155: * @param uidString
156: * @return ComponentAndInterface
157: */
158: public ComponentAndInterface getComponentAndInterfaceForUID(
159: String uidString) {
160: IntKeyWeakReference ref = null;
161: while ((ref = (IntKeyWeakReference) queue.poll()) != null) {
162: directComponentRefs.remove(ref.uid);
163: }
164: int uid = Integer.parseInt(uidString);
165: ComponentAndInterface cai = (ComponentAndInterface) directComponentRefs
166: .get(uid);
167: return cai;
168: }
169:
170: /**
171: * @author jcompagner
172: */
173: public static class ComponentAndInterface {
174: private static final long serialVersionUID = 1L;
175:
176: private final IntKeyWeakReference ref;
177: private final String interfaceName;
178:
179: private ComponentAndInterface(IntKeyWeakReference ref,
180: String interfaceName) {
181: this .ref = ref;
182: this .interfaceName = interfaceName;
183: }
184:
185: /**
186: * @return Component The component that should be used to call the
187: * interface
188: */
189: public Component getComponent() {
190: return (Component) ref.get();
191: }
192:
193: /**
194: * @return String The interface name which should be called on the
195: * component
196: */
197: public String getInterfaceName() {
198: return interfaceName;
199: }
200: }
201:
202: private static class IntKeyWeakReference extends WeakReference {
203: private int uid;
204:
205: /**
206: * @param uid
207: * @param referent
208: * @param q
209: */
210: public IntKeyWeakReference(int uid, Object referent,
211: ReferenceQueue q) {
212: super(referent, q);
213: this.uid = uid;
214: }
215: }
216: }
|