Subversion Repository Public Repository

litesoft

Diff Revisions 949 vs 950 for /trunk/Java/GWT/Client/src/org/litesoft/GWT/client/pavsupport/internal/PanelPlaceActivityHelper.java

Diff revisions: vs.
  @@ -1,238 +1,237 @@
1 - package org.litesoft.GWT.client.pavsupport.internal;
2 -
3 - import org.litesoft.GWT.client.pavsupport.*;
4 - import org.litesoft.commonfoundation.base.*;
5 - import org.litesoft.commonfoundation.typeutils.Objects;
6 -
7 - import com.google.gwt.event.shared.*;
8 - import com.google.gwt.place.shared.*;
9 - import com.google.gwt.user.client.ui.*;
10 -
11 - import java.util.*;
12 -
13 - public class PanelPlaceActivityHelper<CommonActivityParam extends CommonActivityParameter> extends ActivityFactoryRegistry {
14 - private static final Activity NULL_ACTIVITY = new Activity() {
15 - @Override
16 - public String mayStop() {
17 - return null;
18 - }
19 -
20 - @Override
21 - public void onCancel() {
22 - }
23 -
24 - @Override
25 - public void onStop() {
26 - }
27 -
28 - @Override
29 - public void start( AcceptsOneWidget panel ) {
30 - panel.setWidget( new Label( "!" ) );
31 - }
32 - };
33 -
34 - private final AcceptsOneWidget mPanel;
35 - private final CommonActivityParam mCommonActivityParam;
36 - private Activity mCurrentActivity = NULL_ACTIVITY;
37 - private Activity mPendingActivity;
38 - private Place mCurrentPlace = Place.NOWHERE;
39 - private Place mPendingAsyncPlace;
40 - private PlaceChangeListener.Source mPlaceChangerRequestedPlaceSource;
41 - private Place mPlaceChangerRequestedPlace;
42 - private PlaceChangeListener mPlaceChangeListener;
43 -
44 - public PanelPlaceActivityHelper( AcceptsOneWidget pPanel, CommonActivityParam pCommonActivityParam ) {
45 - mPanel = pPanel;
46 - mCommonActivityParam = pCommonActivityParam;
47 - }
48 -
49 - public void add( PlaceChangeListener pPlaceChangeListener ) {
50 - mPlaceChangeListener = pPlaceChangeListener;
51 - }
52 -
53 - public void placeChangeRequested( Place pPlace, PlaceChangeListener.Source pSource ) {
54 - mPlaceChangerRequestedPlace = pPlace;
55 - mPlaceChangerRequestedPlaceSource = pSource;
56 - }
57 -
58 - public Place getCurrentPlace() {
59 - return mCurrentPlace;
60 - }
61 -
62 - public boolean isPendingAsync( Place pPlace ) {
63 - return pPlace.equals( mPendingAsyncPlace );
64 - }
65 -
66 - public void clearPendingAsync() {
67 - mPendingAsyncPlace = null;
68 - }
69 -
70 - public ActivityFactory get( Place pPlace ) {
71 - return get( PlaceIdExtractor.getPlaceId( pPlace ) );
72 - }
73 -
74 - public String getCurrentActivityMayStop() {
75 - return mCurrentActivity.mayStop();
76 - }
77 -
78 - public boolean activate( Place pNewPlace ) {
79 - if ( !isPendingAsync( pNewPlace ) ) {
80 - mPendingAsyncPlace = null;
81 - ActivityFactory zFactory = get( pNewPlace );
82 - if ( zFactory == null ) {
83 - return false;
84 - }
85 - if ( zFactory instanceof ActivityFactory.Asynchronous ) // Un-Happy Case!
86 - {
87 - loadSyncFactory( (ActivityFactory.Asynchronous) zFactory, mPendingAsyncPlace = pNewPlace );
88 - } else {
89 - activate( pNewPlace, (ActivityFactory.Synchronous) zFactory );
90 - }
91 - }
92 - return true;
93 - }
94 -
95 - /**
96 - * Activate the New Place and it's associated Activity (deactivating the current activity.
97 - */
98 - public void activate( Place pNewPlace, ActivityFactory.Synchronous pSyncFactory ) {
99 - Set<Throwable> zIssues = new LinkedHashSet<Throwable>();
100 -
101 - notifyPlaceChangeListener( pNewPlace );
102 - mCurrentPlace = pNewPlace;
103 -
104 - Activity zNewActivity = Objects.deNull( createActivity( zIssues, pSyncFactory, pNewPlace ), NULL_ACTIVITY );
105 -
106 - if ( (mPendingActivity != null) && (mPendingActivity != zNewActivity) ) // The place changed again before the new Activity showed its widget
107 - {
108 - tryCancel( zIssues, mPendingActivity );
109 - }
110 - mPendingActivity = zNewActivity;
111 -
112 - // Wrap the actual panel with a per-call instance that protects the actual panel from canceled or stopped activities, and
113 - // which handles the Pending Activity becoming the Current Activity.
114 - AcceptsOneWidget zPanel = new ProtectedDisplay( zIssues, mPendingActivity );
115 -
116 - if ( !canStart( zIssues, mPendingActivity, zPanel ) ) {
117 - NULL_ACTIVITY.start( new ProtectedDisplay( zIssues, mPendingActivity = NULL_ACTIVITY ) ); // Can NOT fail!
118 - }
119 - }
120 -
121 - private void notifyPlaceChangeListener( Place pNewPlace ) {
122 - if ( mPlaceChangeListener != null ) {
123 - if ( (mPlaceChangerRequestedPlaceSource == null) || //
124 - ((mPlaceChangerRequestedPlaceSource == PlaceChangeListener.Source.Forward) && //
125 - !Objects.areNonArraysEqual( mPlaceChangerRequestedPlace, pNewPlace )) ) {
126 - mPlaceChangerRequestedPlaceSource = PlaceChangeListener.Source.Unexpected;
127 - }
128 - mPlaceChangeListener.placeChange( mPlaceChangerRequestedPlaceSource, mCurrentPlace, pNewPlace );
129 - }
130 - mPlaceChangerRequestedPlaceSource = null;
131 - mPlaceChangerRequestedPlace = null;
132 - }
133 -
134 - @SuppressWarnings({"unchecked"})
135 - protected Activity createActivity( Collection<Throwable> pIssues, ActivityFactory.Synchronous pFactory, Place pPlace ) {
136 - try {
137 - return pFactory.createActivity( mCommonActivityParam, pFactory.getView(), pPlace );
138 - }
139 - catch ( Exception e ) {
140 - pIssues.add( e );
141 - }
142 - return null;
143 - }
144 -
145 - private boolean canStart( Set<Throwable> pIssues, Activity pActivity, AcceptsOneWidget pPanel ) {
146 - try {
147 - pActivity.start( pPanel );
148 - return true;
149 - }
150 - catch ( Exception e ) {
151 - pIssues.add( e );
152 - }
153 - return false;
154 - }
155 -
156 - private void tryCancel( Collection<Throwable> pIssues, Activity pActivity ) {
157 - try {
158 - pActivity.onCancel();
159 - }
160 - catch ( Exception e ) {
161 - pIssues.add( e );
162 - }
163 - }
164 -
165 - private void tryStop( Collection<Throwable> pIssues, Activity pActivity ) {
166 - try {
167 - pActivity.onStop();
168 - }
169 - catch ( Exception e ) {
170 - pIssues.add( e );
171 - }
172 - }
173 -
174 - private void possiblyUpdateActivityAndShowWidget( Set<Throwable> pIssues, Activity pActivity, IsWidget pWidget ) {
175 - if ( mPendingActivity == null ) // Normal? Happy case when No Pending Activity and request is from Current Activity
176 - {
177 - if ( pActivity == mCurrentActivity ) {
178 - showWidget( pWidget );
179 - }
180 - return;
181 - }
182 - if ( pActivity != mPendingActivity ) // Is a Pending Activity, but the request is NOT from it!
183 - {
184 - return;
185 - }
186 - tryStop( pIssues, mCurrentActivity );
187 - mCurrentActivity = mPendingActivity;
188 - mPendingActivity = null;
189 - showWidget( pWidget );
190 - if ( !pIssues.isEmpty() ) {
191 - throw new UmbrellaException( pIssues );
192 - }
193 - }
194 -
195 - private void showWidget( IsWidget pWidget ) {
196 - if ( mPanel != null ) {
197 - mPanel.setWidget( pWidget );
198 - }
199 - }
200 -
201 - @SuppressWarnings({"unchecked"})
202 - private void loadSyncFactory( final ActivityFactory.Asynchronous pAsyncFactory, final Place pPlace ) {
203 - pAsyncFactory.load( mCommonActivityParam, new ActivityFactory.Asynchronous.Callback<CommonActivityParam, IsWidget, Place>() {
204 - @Override
205 - public void loaded( ActivityFactory.Synchronous<CommonActivityParam, IsWidget, Place> pSynchronousFactory ) {
206 - switchAsyncToSync( pPlace, pAsyncFactory, pSynchronousFactory );
207 - }
208 - } );
209 - }
210 -
211 - private void switchAsyncToSync( Place pPlace, ActivityFactory.Asynchronous pAsyncFactory, ActivityFactory.Synchronous pSyncFactory ) {
212 - System.out.println( "Switched " + ClassName.simple( pPlace ) + " from Async to Sync" );
213 - boolean zStillGoing = pPlace.equals( mPendingAsyncPlace );
214 - mPendingAsyncPlace = null;
215 - if ( replace( pAsyncFactory, pSyncFactory ) && zStillGoing ) {
216 - activate( pPlace, pSyncFactory );
217 - }
218 - }
219 -
220 - /**
221 - * Wraps our real display to prevent an Activity from taking it over if it is
222 - * not the currentActivity.
223 - */
224 - private class ProtectedDisplay implements AcceptsOneWidget {
225 - private final Set<Throwable> mIssues;
226 - private final Activity mExpectedActivity;
227 -
228 - ProtectedDisplay( Set<Throwable> pIssues, Activity pExpectedActivity ) {
229 - mIssues = pIssues;
230 - mExpectedActivity = pExpectedActivity;
231 - }
232 -
233 - @Override
234 - public void setWidget( IsWidget pWidget ) {
235 - possiblyUpdateActivityAndShowWidget( mIssues, mExpectedActivity, pWidget );
236 - }
237 - }
238 - }
1 + package org.litesoft.GWT.client.pavsupport.internal;
2 +
3 + import org.litesoft.GWT.client.pavsupport.*;
4 + import org.litesoft.commonfoundation.base.*;
5 +
6 + import com.google.gwt.event.shared.*;
7 + import com.google.gwt.place.shared.*;
8 + import com.google.gwt.user.client.ui.*;
9 +
10 + import java.util.*;
11 +
12 + public class PanelPlaceActivityHelper<CommonActivityParam extends CommonActivityParameter> extends ActivityFactoryRegistry {
13 + private static final Activity NULL_ACTIVITY = new Activity() {
14 + @Override
15 + public String mayStop() {
16 + return null;
17 + }
18 +
19 + @Override
20 + public void onCancel() {
21 + }
22 +
23 + @Override
24 + public void onStop() {
25 + }
26 +
27 + @Override
28 + public void start( AcceptsOneWidget panel ) {
29 + panel.setWidget( new Label( "!" ) );
30 + }
31 + };
32 +
33 + private final AcceptsOneWidget mPanel;
34 + private final CommonActivityParam mCommonActivityParam;
35 + private Activity mCurrentActivity = NULL_ACTIVITY;
36 + private Activity mPendingActivity;
37 + private Place mCurrentPlace = Place.NOWHERE;
38 + private Place mPendingAsyncPlace;
39 + private PlaceChangeListener.Source mPlaceChangerRequestedPlaceSource;
40 + private Place mPlaceChangerRequestedPlace;
41 + private PlaceChangeListener mPlaceChangeListener;
42 +
43 + public PanelPlaceActivityHelper( AcceptsOneWidget pPanel, CommonActivityParam pCommonActivityParam ) {
44 + mPanel = pPanel;
45 + mCommonActivityParam = pCommonActivityParam;
46 + }
47 +
48 + public void add( PlaceChangeListener pPlaceChangeListener ) {
49 + mPlaceChangeListener = pPlaceChangeListener;
50 + }
51 +
52 + public void placeChangeRequested( Place pPlace, PlaceChangeListener.Source pSource ) {
53 + mPlaceChangerRequestedPlace = pPlace;
54 + mPlaceChangerRequestedPlaceSource = pSource;
55 + }
56 +
57 + public Place getCurrentPlace() {
58 + return mCurrentPlace;
59 + }
60 +
61 + public boolean isPendingAsync( Place pPlace ) {
62 + return pPlace.equals( mPendingAsyncPlace );
63 + }
64 +
65 + public void clearPendingAsync() {
66 + mPendingAsyncPlace = null;
67 + }
68 +
69 + public ActivityFactory get( Place pPlace ) {
70 + return get( PlaceIdExtractor.getPlaceId( pPlace ) );
71 + }
72 +
73 + public String getCurrentActivityMayStop() {
74 + return mCurrentActivity.mayStop();
75 + }
76 +
77 + public boolean activate( Place pNewPlace ) {
78 + if ( !isPendingAsync( pNewPlace ) ) {
79 + mPendingAsyncPlace = null;
80 + ActivityFactory zFactory = get( pNewPlace );
81 + if ( zFactory == null ) {
82 + return false;
83 + }
84 + if ( zFactory instanceof ActivityFactory.Asynchronous ) // Un-Happy Case!
85 + {
86 + loadSyncFactory( (ActivityFactory.Asynchronous) zFactory, mPendingAsyncPlace = pNewPlace );
87 + } else {
88 + activate( pNewPlace, (ActivityFactory.Synchronous) zFactory );
89 + }
90 + }
91 + return true;
92 + }
93 +
94 + /**
95 + * Activate the New Place and it's associated Activity (deactivating the current activity.
96 + */
97 + public void activate( Place pNewPlace, ActivityFactory.Synchronous pSyncFactory ) {
98 + Set<Throwable> zIssues = new LinkedHashSet<Throwable>();
99 +
100 + notifyPlaceChangeListener( pNewPlace );
101 + mCurrentPlace = pNewPlace;
102 +
103 + Activity zNewActivity = ConstrainTo.notNull( createActivity( zIssues, pSyncFactory, pNewPlace ), NULL_ACTIVITY );
104 +
105 + if ( (mPendingActivity != null) && (mPendingActivity != zNewActivity) ) // The place changed again before the new Activity showed its widget
106 + {
107 + tryCancel( zIssues, mPendingActivity );
108 + }
109 + mPendingActivity = zNewActivity;
110 +
111 + // Wrap the actual panel with a per-call instance that protects the actual panel from canceled or stopped activities, and
112 + // which handles the Pending Activity becoming the Current Activity.
113 + AcceptsOneWidget zPanel = new ProtectedDisplay( zIssues, mPendingActivity );
114 +
115 + if ( !canStart( zIssues, mPendingActivity, zPanel ) ) {
116 + NULL_ACTIVITY.start( new ProtectedDisplay( zIssues, mPendingActivity = NULL_ACTIVITY ) ); // Can NOT fail!
117 + }
118 + }
119 +
120 + private void notifyPlaceChangeListener( Place pNewPlace ) {
121 + if ( mPlaceChangeListener != null ) {
122 + if ( (mPlaceChangerRequestedPlaceSource == null) || //
123 + ((mPlaceChangerRequestedPlaceSource == PlaceChangeListener.Source.Forward) && //
124 + !Currently.areEqual( mPlaceChangerRequestedPlace, pNewPlace )) ) {
125 + mPlaceChangerRequestedPlaceSource = PlaceChangeListener.Source.Unexpected;
126 + }
127 + mPlaceChangeListener.placeChange( mPlaceChangerRequestedPlaceSource, mCurrentPlace, pNewPlace );
128 + }
129 + mPlaceChangerRequestedPlaceSource = null;
130 + mPlaceChangerRequestedPlace = null;
131 + }
132 +
133 + @SuppressWarnings({"unchecked"})
134 + protected Activity createActivity( Collection<Throwable> pIssues, ActivityFactory.Synchronous pFactory, Place pPlace ) {
135 + try {
136 + return pFactory.createActivity( mCommonActivityParam, pFactory.getView(), pPlace );
137 + }
138 + catch ( Exception e ) {
139 + pIssues.add( e );
140 + }
141 + return null;
142 + }
143 +
144 + private boolean canStart( Set<Throwable> pIssues, Activity pActivity, AcceptsOneWidget pPanel ) {
145 + try {
146 + pActivity.start( pPanel );
147 + return true;
148 + }
149 + catch ( Exception e ) {
150 + pIssues.add( e );
151 + }
152 + return false;
153 + }
154 +
155 + private void tryCancel( Collection<Throwable> pIssues, Activity pActivity ) {
156 + try {
157 + pActivity.onCancel();
158 + }
159 + catch ( Exception e ) {
160 + pIssues.add( e );
161 + }
162 + }
163 +
164 + private void tryStop( Collection<Throwable> pIssues, Activity pActivity ) {
165 + try {
166 + pActivity.onStop();
167 + }
168 + catch ( Exception e ) {
169 + pIssues.add( e );
170 + }
171 + }
172 +
173 + private void possiblyUpdateActivityAndShowWidget( Set<Throwable> pIssues, Activity pActivity, IsWidget pWidget ) {
174 + if ( mPendingActivity == null ) // Normal? Happy case when No Pending Activity and request is from Current Activity
175 + {
176 + if ( pActivity == mCurrentActivity ) {
177 + showWidget( pWidget );
178 + }
179 + return;
180 + }
181 + if ( pActivity != mPendingActivity ) // Is a Pending Activity, but the request is NOT from it!
182 + {
183 + return;
184 + }
185 + tryStop( pIssues, mCurrentActivity );
186 + mCurrentActivity = mPendingActivity;
187 + mPendingActivity = null;
188 + showWidget( pWidget );
189 + if ( !pIssues.isEmpty() ) {
190 + throw new UmbrellaException( pIssues );
191 + }
192 + }
193 +
194 + private void showWidget( IsWidget pWidget ) {
195 + if ( mPanel != null ) {
196 + mPanel.setWidget( pWidget );
197 + }
198 + }
199 +
200 + @SuppressWarnings({"unchecked"})
201 + private void loadSyncFactory( final ActivityFactory.Asynchronous pAsyncFactory, final Place pPlace ) {
202 + pAsyncFactory.load( mCommonActivityParam, new ActivityFactory.Asynchronous.Callback<CommonActivityParam, IsWidget, Place>() {
203 + @Override
204 + public void loaded( ActivityFactory.Synchronous<CommonActivityParam, IsWidget, Place> pSynchronousFactory ) {
205 + switchAsyncToSync( pPlace, pAsyncFactory, pSynchronousFactory );
206 + }
207 + } );
208 + }
209 +
210 + private void switchAsyncToSync( Place pPlace, ActivityFactory.Asynchronous pAsyncFactory, ActivityFactory.Synchronous pSyncFactory ) {
211 + System.out.println( "Switched " + ClassName.simple( pPlace ) + " from Async to Sync" );
212 + boolean zStillGoing = pPlace.equals( mPendingAsyncPlace );
213 + mPendingAsyncPlace = null;
214 + if ( replace( pAsyncFactory, pSyncFactory ) && zStillGoing ) {
215 + activate( pPlace, pSyncFactory );
216 + }
217 + }
218 +
219 + /**
220 + * Wraps our real display to prevent an Activity from taking it over if it is
221 + * not the currentActivity.
222 + */
223 + private class ProtectedDisplay implements AcceptsOneWidget {
224 + private final Set<Throwable> mIssues;
225 + private final Activity mExpectedActivity;
226 +
227 + ProtectedDisplay( Set<Throwable> pIssues, Activity pExpectedActivity ) {
228 + mIssues = pIssues;
229 + mExpectedActivity = pExpectedActivity;
230 + }
231 +
232 + @Override
233 + public void setWidget( IsWidget pWidget ) {
234 + possiblyUpdateActivityAndShowWidget( mIssues, mExpectedActivity, pWidget );
235 + }
236 + }
237 + }