1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.layout.impl;
18
19 import java.util.List;
20 import java.util.Map;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.jetspeed.JetspeedActions;
25 import org.apache.jetspeed.ajax.AJAXException;
26 import org.apache.jetspeed.ajax.AjaxAction;
27 import org.apache.jetspeed.ajax.AjaxBuilder;
28 import org.apache.jetspeed.components.portletregistry.PortletRegistry;
29 import org.apache.jetspeed.layout.PortletActionSecurityBehavior;
30 import org.apache.jetspeed.om.page.Fragment;
31 import org.apache.jetspeed.om.page.Page;
32 import org.apache.jetspeed.page.PageManager;
33 import org.apache.jetspeed.request.RequestContext;
34
35
36 /***
37 * Add Portlet portlet placement action
38 *
39 * AJAX Parameters:
40 * id = portlet full name (pa::portletName) to be added
41 * page = (implied in the URL)
42 * Optional Parameters:
43 * row = the new row to move to
44 * col = the new column to move to
45 *
46 * @author <a>David Gurney </a>
47 * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
48 * @version $Id: $
49 */
50 public class AddPortletAction
51 extends MovePortletAction
52 implements AjaxAction, AjaxBuilder, Constants
53 {
54 protected Log log = LogFactory.getLog(AddPortletAction.class);
55 protected GetPortletsAction getPortletsAction = null;
56 protected boolean allowDuplicatePortlets = true;
57
58 public AddPortletAction( String template, String errorTemplate, PortletRegistry registry, GetPortletsAction getPortletsAction )
59 throws AJAXException
60 {
61 this( template, errorTemplate, registry, null, null, getPortletsAction, true );
62 }
63
64 public AddPortletAction( String template,
65 String errorTemplate,
66 PortletRegistry registry,
67 PageManager pageManager,
68 PortletActionSecurityBehavior securityBehavior,
69 GetPortletsAction getPortletsAction )
70 throws AJAXException
71 {
72 this( template, errorTemplate, registry, pageManager, securityBehavior, getPortletsAction, true );
73 }
74
75 public AddPortletAction( String template,
76 String errorTemplate,
77 PortletRegistry registry,
78 PageManager pageManager,
79 PortletActionSecurityBehavior securityBehavior,
80 GetPortletsAction getPortletsAction,
81 boolean allowDuplicatePortlets )
82 throws AJAXException
83 {
84 super( template, errorTemplate, registry, pageManager, securityBehavior );
85 this.getPortletsAction = getPortletsAction;
86 this.allowDuplicatePortlets = allowDuplicatePortlets;
87 }
88
89 protected boolean runAction( RequestContext requestContext, Map resultMap, boolean batch ) throws AJAXException
90 {
91 boolean success = true;
92 String status = "success";
93 try
94 {
95 resultMap.put( ACTION, "add" );
96
97 String portletId = getActionParameter( requestContext, PORTLETID );
98 if (portletId == null)
99 {
100 throw new RuntimeException( "portlet id not provided" );
101 }
102 resultMap.put( PORTLETID, portletId );
103
104
105
106 verifyPortletId( requestContext, portletId );
107
108 if( allowDuplicatePortlets == false )
109 {
110
111 checkForDuplicatePortlet( requestContext, resultMap, portletId );
112 }
113
114 String layoutId = getActionParameter( requestContext, LAYOUTID );
115
116 if ( false == checkAccess( requestContext, JetspeedActions.EDIT ) )
117 {
118 NestedFragmentContext addToFragmentContext = null;
119 if ( layoutId != null && layoutId.length() > 0 )
120 {
121 Page page = requestContext.getPage();
122 Fragment fragment = page.getFragmentById( layoutId );
123 if ( fragment == null )
124 {
125 success = false;
126 resultMap.put( REASON, "Specified layout fragment not found: " + layoutId );
127 return success;
128 }
129
130 try
131 {
132 addToFragmentContext = new NestedFragmentContext( fragment, page, getPortletRegistry() );
133 }
134 catch ( Exception ex )
135 {
136 log.error( "Failure to construct nested context for fragment " + layoutId, ex );
137 success = false;
138 resultMap.put( REASON, "Cannot construct nested context for specified layout fragment" );
139 return success;
140 }
141 }
142
143 if ( ! createNewPageOnEdit( requestContext ) )
144 {
145 success = false;
146 resultMap.put( REASON, "Insufficient access to edit page" );
147 return success;
148 }
149 status = "refresh";
150
151 if ( addToFragmentContext != null )
152 {
153 Page newPage = requestContext.getPage();
154
155
156 Fragment newFragment = null;
157 try
158 {
159 newFragment = addToFragmentContext.getFragmentOnNewPage( newPage, getPortletRegistry() );
160 }
161 catch ( Exception ex )
162 {
163 log.error( "Failure to locate copy of fragment " + layoutId, ex );
164 success = false;
165 resultMap.put( REASON, "Failed to find new fragment for specified layout id: " + layoutId );
166 return success;
167 }
168 layoutId = newFragment.getId();
169 }
170 }
171
172 Page page = requestContext.getPage();
173
174 Fragment fragment = pageManager.newFragment();
175 fragment.setType( Fragment.PORTLET );
176 fragment.setName( portletId );
177
178 Fragment placeInLayoutFragment = null;
179 if ( layoutId != null && layoutId.length() > 0 )
180 {
181 placeInLayoutFragment = page.getFragmentById( layoutId );
182 if ( placeInLayoutFragment == null )
183 {
184 throw new Exception( "layout id not found: " + layoutId );
185 }
186 }
187 else
188 {
189 placeInLayoutFragment = page.getRootFragment();
190 }
191
192 success = placeFragment( requestContext,
193 batch,
194 resultMap,
195 fragment,
196 placeInLayoutFragment ) ;
197
198 resultMap.put( PORTLETENTITY, fragment.getId() );
199 if ( success )
200 {
201 resultMap.put( STATUS, status );
202 }
203 }
204 catch ( Exception e )
205 {
206
207 log.error("exception while adding a portlet", e);
208 resultMap.put(REASON, e.toString());
209
210
211 success = false;
212 }
213
214 return success;
215 }
216
217 protected void verifyPortletId(RequestContext requestContext, String portletId) throws Exception
218 {
219
220 List portletList = getPortletsAction.retrievePortlets(requestContext, null);
221 if(portletList != null) {
222 for(int i = 0; i < portletList.size(); i++) {
223 PortletInfo portletInfo = (PortletInfo)portletList.get(i);
224 if(portletInfo != null) {
225 if(portletInfo.getName().equalsIgnoreCase(portletId)) {
226
227 return;
228 }
229 }
230 }
231 }
232
233 throw new Exception(portletId + " is not a valid portlet or not allowed for this user");
234 }
235
236 protected void checkForDuplicatePortlet(RequestContext requestContext, Map resultMap, String portletId)
237 throws AJAXException
238 {
239
240 Page page = requestContext.getPage();
241
242 boolean duplicateFound = isDuplicateFragment(page.getRootFragment(), portletId);
243
244
245 if(duplicateFound == true) {
246 throw new AJAXException(portletId + " is already on the page, duplicates are not allowed");
247 }
248 }
249
250 protected boolean isDuplicateFragment(Fragment fragment, String portletId) {
251 if(fragment != null) {
252
253 String fragmentName = fragment.getName();
254 if(fragmentName.equals(portletId)) {
255
256 return true;
257 } else {
258
259 List childFragments = fragment.getFragments();
260 if(childFragments != null) {
261 for(int i = 0; i < childFragments.size(); i++) {
262
263 if(isDuplicateFragment((Fragment)childFragments.get(i),portletId) == true) {
264
265 return true;
266 }
267 }
268 }
269 }
270 }
271
272 return false;
273 }
274 }