|
@@ -2,17 +2,18 @@ |
2 |
2 |
|
|
3 |
3 |
|
import java.util.*; |
4 |
4 |
|
|
|
5 |
+ |
import org.litesoft.logger.*; |
5 |
6 |
|
import org.litesoft.sandbox.multimodule.common.client.support.*; |
6 |
7 |
|
|
7 |
8 |
|
import com.google.gwt.place.shared.*; |
8 |
9 |
|
|
9 |
10 |
|
/** |
10 |
|
- |
* Supporting class that implements PlaceHistoryMapper which expect PlaceTokenizer(s) and Place(s) that implement HasPlaceId, |
11 |
|
- |
* otherwise Class Name magic is used (The Tokenizer MUST be a static inner class of it's Place). |
|
11 |
+ |
* Supporting class that implements PlaceHistoryMapper which expects PlaceTokenizer(s) and Place(s) that implement HasPlaceId, |
|
12 |
+ |
* otherwise Class Name magic is used (See PlaceIdExtractor). |
12 |
13 |
|
*/ |
13 |
14 |
|
public class PlaceRegistry implements PlaceHistoryMapper |
14 |
15 |
|
{ |
15 |
|
- |
public static final PlaceRegistry INSTANCE = new PlaceRegistry(); |
|
16 |
+ |
private static final Logger LOGGER = LoggerFactory.getLogger( PlaceRegistry.class ); |
16 |
17 |
|
|
17 |
18 |
|
private static final PlaceTokenizerMap PLACE_TOKENIZER_MAP = new PlaceTokenizerMap(); |
18 |
19 |
|
private static IdTokenizer<Place> sDefaultTokenizer; |
|
@@ -36,7 +37,8 @@ |
36 |
37 |
|
{ |
37 |
38 |
|
if ( pDefaultTokenizer != null ) |
38 |
39 |
|
{ |
39 |
|
- |
if ( null != (sDefaultTokenizer = ProxyIdTokenizer.forceToIdTokenizer( PLACE_TOKENIZER_MAP.addTokenizer( pDefaultTokenizer ) )) ) |
|
40 |
+ |
PlaceTokenizer<Place> zTokenizer = cast( pDefaultTokenizer ); |
|
41 |
+ |
if ( null != (sDefaultTokenizer = ProxyIdTokenizer.forceToIdTokenizer( PLACE_TOKENIZER_MAP.addTokenizer( zTokenizer ), zTokenizer )) ) |
40 |
42 |
|
{ |
41 |
43 |
|
sDefaultPlace = sDefaultTokenizer.getPlace( null ); |
42 |
44 |
|
} |
|
@@ -48,8 +50,11 @@ |
48 |
50 |
|
return sDefaultPlace; |
49 |
51 |
|
} |
50 |
52 |
|
|
51 |
|
- |
private PlaceRegistry() |
|
53 |
+ |
private MessageUserSinkAccessor mMessageUserSinkAccessor; |
|
54 |
+ |
|
|
55 |
+ |
public PlaceRegistry( MessageUserSinkAccessor pMessageUserSinkAccessor ) |
52 |
56 |
|
{ |
|
57 |
+ |
mMessageUserSinkAccessor = (pMessageUserSinkAccessor != null) ? pMessageUserSinkAccessor : DefaultMessageUserSink.FACTORY; |
53 |
58 |
|
} |
54 |
59 |
|
|
55 |
60 |
|
/** |
|
@@ -65,10 +70,36 @@ |
65 |
70 |
|
PlaceIdAndData zIdAndData = PlaceIdAndData.fromString( pToken ); |
66 |
71 |
|
if ( zIdAndData != null ) |
67 |
72 |
|
{ |
68 |
|
- |
PlaceTokenizer<? extends Place> zTokenizer = PLACE_TOKENIZER_MAP.getTokenizer( zIdAndData.getPlaceID() ); |
69 |
|
- |
if ( zTokenizer != null ) |
|
73 |
+ |
String zPlaceId = zIdAndData.getPlaceId(); |
|
74 |
+ |
PlaceTokenizer<? extends Place> zTokenizer = PLACE_TOKENIZER_MAP.getTokenizer( zPlaceId ); |
|
75 |
+ |
if ( zTokenizer == null ) |
|
76 |
+ |
{ |
|
77 |
+ |
mMessageUserSinkAccessor.getMessageUserSink().setErrorMessage( "Unable to determine 'view' from: " + zPlaceId ); |
|
78 |
+ |
} |
|
79 |
+ |
else |
70 |
80 |
|
{ |
71 |
|
- |
return UtilsCommon.deNull( zTokenizer.getPlace( zIdAndData.getData() ), sDefaultPlace ); |
|
81 |
+ |
Place zPlace; |
|
82 |
+ |
|
|
83 |
+ |
try |
|
84 |
+ |
{ |
|
85 |
+ |
if ( null != (zPlace = zTokenizer.getPlace( zIdAndData.getData() )) ) |
|
86 |
+ |
{ |
|
87 |
+ |
return zPlace; |
|
88 |
+ |
} |
|
89 |
+ |
} |
|
90 |
+ |
catch ( RuntimeException e ) |
|
91 |
+ |
{ |
|
92 |
+ |
String zMessage = "Unable to create 'view' from: "; |
|
93 |
+ |
LOGGER.warn.log( e, zMessage, pToken ); |
|
94 |
+ |
mMessageUserSinkAccessor.getMessageUserSink().setErrorMessage( zMessage + zPlaceId ); |
|
95 |
+ |
return sDefaultPlace; |
|
96 |
+ |
} |
|
97 |
+ |
if ( zPlace == null ) |
|
98 |
+ |
{ |
|
99 |
+ |
String zMessage = "No 'view' from: "; |
|
100 |
+ |
LOGGER.warn.log( zMessage, pToken ); |
|
101 |
+ |
mMessageUserSinkAccessor.getMessageUserSink().setErrorMessage( zMessage + zPlaceId ); |
|
102 |
+ |
} |
72 |
103 |
|
} |
73 |
104 |
|
} |
74 |
105 |
|
return sDefaultPlace; |
|
@@ -84,10 +115,22 @@ |
84 |
115 |
|
@Override |
85 |
116 |
|
public String getToken( Place pPlace ) |
86 |
117 |
|
{ |
87 |
|
- |
String zPlaceId = PLACE_TOKENIZER_MAP.getPlaceId( pPlace ); |
|
118 |
+ |
if ( pPlace == null ) |
|
119 |
+ |
{ |
|
120 |
+ |
return null; |
|
121 |
+ |
} |
|
122 |
+ |
String zPlaceId = PlaceIdExtractor.getPlaceId( pPlace ); |
|
123 |
+ |
if ( zPlaceId == null ) |
|
124 |
+ |
{ |
|
125 |
+ |
mMessageUserSinkAccessor.getMessageUserSink().setErrorMessage( "Unable to determine 'view' from class: " + pPlace.getClass().getName() ); |
|
126 |
+ |
return null; |
|
127 |
+ |
} |
88 |
128 |
|
PlaceTokenizer<Place> zTokenizer = PLACE_TOKENIZER_MAP.getTokenizer( zPlaceId ); |
89 |
129 |
|
if ( zTokenizer == null ) |
90 |
130 |
|
{ |
|
131 |
+ |
String zMessage = "No 'view' for '" + zPlaceId + "'"; |
|
132 |
+ |
LOGGER.error.log( zMessage, ": ", pPlace.getClass().getName() ); |
|
133 |
+ |
mMessageUserSinkAccessor.getMessageUserSink().setErrorMessage( zMessage ); |
91 |
134 |
|
if ( null == sDefaultTokenizer ) |
92 |
135 |
|
{ |
93 |
136 |
|
return null; |
|
@@ -96,7 +139,16 @@ |
96 |
139 |
|
pPlace = sDefaultPlace; |
97 |
140 |
|
zPlaceId = sDefaultTokenizer.getPlaceId(); |
98 |
141 |
|
} |
99 |
|
- |
return new PlaceIdAndData( zPlaceId, zTokenizer.getToken( pPlace ) ).toString(); |
|
142 |
+ |
String zToken = null; |
|
143 |
+ |
try |
|
144 |
+ |
{ |
|
145 |
+ |
zToken = zTokenizer.getToken( pPlace ); |
|
146 |
+ |
} |
|
147 |
+ |
catch ( RuntimeException e ) |
|
148 |
+ |
{ |
|
149 |
+ |
LOGGER.error.log( e, "Unable to 'tokenize' Place: ", pPlace.getClass(), " with PlaceId '", zPlaceId, "'" ); |
|
150 |
+ |
} |
|
151 |
+ |
return new PlaceIdAndData( zPlaceId, zToken ).toString(); |
100 |
152 |
|
} |
101 |
153 |
|
|
102 |
154 |
|
@SuppressWarnings({"unchecked"}) |
|
@@ -109,7 +161,7 @@ |
109 |
161 |
|
{ |
110 |
162 |
|
private PlaceTokenizer<T> mTokenizer; |
111 |
163 |
|
|
112 |
|
- |
protected ProxyIdTokenizer( PlaceTokenizer<T> pTokenizer, Object pPlaceId ) |
|
164 |
+ |
protected ProxyIdTokenizer( Object pPlaceId, PlaceTokenizer<T> pTokenizer ) |
113 |
165 |
|
{ |
114 |
166 |
|
super( pPlaceId ); |
115 |
167 |
|
mTokenizer = pTokenizer; |
|
@@ -127,42 +179,37 @@ |
127 |
179 |
|
return mTokenizer.getToken( pPlace ); |
128 |
180 |
|
} |
129 |
181 |
|
|
130 |
|
- |
public static <T extends Place> IdTokenizer<T> forceToIdTokenizer( PlaceTokenizer<T> pTokenizer ) |
|
182 |
+ |
public static <T extends Place> IdTokenizer<T> forceToIdTokenizer( String pPlaceId, PlaceTokenizer<T> pTokenizer ) |
131 |
183 |
|
{ |
132 |
|
- |
if ( pTokenizer instanceof IdTokenizer ) |
133 |
|
- |
{ |
134 |
|
- |
return (IdTokenizer<T>) pTokenizer; |
135 |
|
- |
} |
136 |
|
- |
if ( pTokenizer instanceof HasPlaceId ) |
137 |
|
- |
{ |
138 |
|
- |
return new ProxyIdTokenizer<T>( pTokenizer, ((HasPlaceId) pTokenizer).getPlaceId() ); |
139 |
|
- |
} |
140 |
|
- |
return null; |
|
184 |
+ |
return (pTokenizer instanceof IdTokenizer) ? (IdTokenizer<T>) pTokenizer : new ProxyIdTokenizer<T>( pPlaceId, pTokenizer ); |
141 |
185 |
|
} |
142 |
186 |
|
} |
143 |
187 |
|
|
144 |
188 |
|
private static class PlaceTokenizerMap |
145 |
189 |
|
{ |
146 |
|
- |
Map<String, PlaceTokenizer<Place>> mPlaceIdToTokenizers = new HashMap<String, PlaceTokenizer<Place>>(); |
|
190 |
+ |
private final Map<String, PlaceTokenizer<Place>> mPlaceIdToTokenizers = new HashMap<String, PlaceTokenizer<Place>>(); |
147 |
191 |
|
|
148 |
|
- |
public PlaceTokenizer<Place> addTokenizer( PlaceTokenizer<? extends Place> pTokenizer ) |
|
192 |
+ |
/** |
|
193 |
+ |
* @param pTokenizer !null |
|
194 |
+ |
* |
|
195 |
+ |
* @return PlaceId |
|
196 |
+ |
*/ |
|
197 |
+ |
public String addTokenizer( PlaceTokenizer<? extends Place> pTokenizer ) |
149 |
198 |
|
{ |
150 |
199 |
|
PlaceTokenizer<Place> zTokenizer = cast( pTokenizer ); |
151 |
|
- |
if ( !(zTokenizer instanceof HasPlaceId) ) |
|
200 |
+ |
String zPlaceId = PlaceIdExtractor.getPlaceId( zTokenizer ); |
|
201 |
+ |
if ( null == zPlaceId ) |
152 |
202 |
|
{ |
153 |
|
- |
throw new IllegalStateException( "Attempt to add PlaceTokenizer that does NOT implement HasPlaceId: " + pTokenizer ); |
|
203 |
+ |
throw new IllegalStateException( "Unable to determine PlaceId from Tokenizer: " + pTokenizer.getClass().getName() ); |
154 |
204 |
|
} |
155 |
|
- |
mPlaceIdToTokenizers.put( ((HasPlaceId) zTokenizer).getPlaceId(), zTokenizer ); |
156 |
|
- |
return zTokenizer; |
157 |
|
- |
} |
158 |
|
- |
|
159 |
|
- |
public String getPlaceId( Place pPlace ) |
160 |
|
- |
{ |
161 |
|
- |
if ( pPlace instanceof HasPlaceId ) |
|
205 |
+ |
PlaceTokenizer<Place> zPreviousTokenizer = mPlaceIdToTokenizers.put( zPlaceId, zTokenizer ); |
|
206 |
+ |
if ( (zPreviousTokenizer != null) && (zPreviousTokenizer != zTokenizer) ) |
162 |
207 |
|
{ |
163 |
|
- |
return ((HasPlaceId) pPlace).getPlaceId(); |
|
208 |
+ |
throw new IllegalStateException( "Duplicate registration for PlaceId '':" + // |
|
209 |
+ |
"\n " + zPreviousTokenizer.getClass().getName() + // |
|
210 |
+ |
"\n " + pTokenizer.getClass().getName() ); |
164 |
211 |
|
} |
165 |
|
- |
throw new IllegalStateException( "Attempt to fetch PlaceTokenizer with a Place that does NOT implement HasPlaceId: " + pPlace ); |
|
212 |
+ |
return zPlaceId; |
166 |
213 |
|
} |
167 |
214 |
|
|
168 |
215 |
|
public PlaceTokenizer<Place> getTokenizer( String pPlaceId ) |
|
@@ -173,17 +220,17 @@ |
173 |
220 |
|
|
174 |
221 |
|
private static class PlaceIdAndData |
175 |
222 |
|
{ |
176 |
|
- |
private String mPlaceID, mData; |
|
223 |
+ |
private String mPlaceId, mData; |
177 |
224 |
|
|
178 |
|
- |
public PlaceIdAndData( String pPlaceID, String pData ) |
|
225 |
+ |
public PlaceIdAndData( String pPlaceId, String pData ) |
179 |
226 |
|
{ |
180 |
|
- |
mPlaceID = UtilsCommon.assertNotEmpty( "PlaceID", pPlaceID ); |
|
227 |
+ |
mPlaceId = UtilsCommon.assertNotEmpty( "PlaceID", pPlaceId ); |
181 |
228 |
|
mData = UtilsCommon.noEmpty( pData ); |
182 |
229 |
|
} |
183 |
230 |
|
|
184 |
|
- |
public String getPlaceID() |
|
231 |
+ |
public String getPlaceId() |
185 |
232 |
|
{ |
186 |
|
- |
return mPlaceID; |
|
233 |
+ |
return mPlaceId; |
187 |
234 |
|
} |
188 |
235 |
|
|
189 |
236 |
|
public String getData() |
|
@@ -194,7 +241,7 @@ |
194 |
241 |
|
@Override |
195 |
242 |
|
public String toString() |
196 |
243 |
|
{ |
197 |
|
- |
return (mData == null) ? mPlaceID : mPlaceID + ':' + mData; |
|
244 |
+ |
return (mData == null) ? mPlaceId : mPlaceId + ':' + mData; |
198 |
245 |
|
} |
199 |
246 |
|
|
200 |
247 |
|
public static PlaceIdAndData fromString( String pURLfragment ) |
|
@@ -204,14 +251,18 @@ |
204 |
251 |
|
if ( (pURLfragment = pURLfragment.trim()).length() != 0 ) |
205 |
252 |
|
{ |
206 |
253 |
|
int at = pURLfragment.indexOf( ':' ); |
207 |
|
- |
if ( at != 0 ) |
|
254 |
+ |
if ( at == 0 ) |
|
255 |
+ |
{ |
|
256 |
+ |
LOGGER.error.log( "Invalid URLfragment: '", pURLfragment, "'" ); |
|
257 |
+ |
} |
|
258 |
+ |
else |
208 |
259 |
|
{ |
209 |
260 |
|
String zData = null; |
210 |
261 |
|
String zPlaceID = pURLfragment; |
211 |
262 |
|
if ( at != -1 ) |
212 |
263 |
|
{ |
213 |
264 |
|
zPlaceID = pURLfragment.substring( 0, at ).trim(); |
214 |
|
- |
zData = UtilsCommon.noEmpty( pURLfragment.substring( at + 1 ) ); |
|
265 |
+ |
zData = pURLfragment.substring( at + 1 ); |
215 |
266 |
|
} |
216 |
267 |
|
return new PlaceIdAndData( zPlaceID, zData ); |
217 |
268 |
|
} |