View Javadoc

1   /* 
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8   *
9   *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17  package org.apache.jetspeed.portlets.selector;
18  
19  import java.io.IOException;
20  import java.sql.Types;
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Locale;
27  import java.util.Map;
28  import java.util.Set;
29  import java.util.StringTokenizer;
30  
31  import javax.portlet.ActionRequest;
32  import javax.portlet.ActionResponse;
33  import javax.portlet.PortletConfig;
34  import javax.portlet.PortletException;
35  import javax.portlet.RenderRequest;
36  import javax.portlet.RenderResponse;
37  
38  import org.apache.jetspeed.CommonPortletServices;
39  import org.apache.jetspeed.JetspeedActions;
40  import org.apache.jetspeed.components.portletregistry.PortletRegistry;
41  import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
42  import org.apache.jetspeed.om.common.portlet.PortletDefinitionComposite;
43  import org.apache.jetspeed.portlets.PortletInfo;
44  import org.apache.jetspeed.portlets.pam.PortletApplicationResources;
45  import org.apache.jetspeed.search.ParsedObject;
46  import org.apache.jetspeed.search.SearchEngine;
47  import org.apache.jetspeed.security.SecurityAccessController;
48  import org.apache.portals.gems.browser.BrowserIterator;
49  import org.apache.portals.gems.browser.BrowserPortlet;
50  import org.apache.portals.gems.util.StatusMessage;
51  import org.apache.portals.messaging.PortletMessaging;
52  
53  /***
54   * Selects one or more portlets
55   * 
56   * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
57   * @version $Id: PortletSelector.java 348264 2005-11-22 22:06:45Z taylor $
58   */
59  public class PortletSelector extends BrowserPortlet
60  {
61      
62      protected static final String CHECKEDSET = "checkedSet";
63      protected static final String UNCHECKEDSET = "unCheckedSet";
64     
65      protected SecurityAccessController securityAccessController;
66      protected PortletRegistry registry;
67      protected SearchEngine searchEngine;
68      
69      public void init(PortletConfig config)
70      throws PortletException 
71      {
72          super.init(config);
73          context = getPortletContext();                
74          registry = (PortletRegistry)context.getAttribute(CommonPortletServices.CPS_REGISTRY_COMPONENT);
75          if (null == registry)
76          {
77              throw new PortletException("Failed to find the Portlet Registry on portlet initialization");
78          }        
79          searchEngine = (SearchEngine)context.getAttribute(CommonPortletServices.CPS_SEARCH_COMPONENT);
80          if (null == searchEngine)
81          {
82              throw new PortletException("Failed to find the Search Engine on portlet initialization");
83          }        
84          securityAccessController = (SecurityAccessController)context.getAttribute(CommonPortletServices.CPS_SECURITY_ACCESS_CONTROLLER);
85          if (null == securityAccessController)
86          {
87              throw new PortletException("Failed to find the Security Access Controller on portlet initialization");
88          }        
89      }
90            
91      public void doView(RenderRequest request, RenderResponse response)
92      throws PortletException, IOException
93      {
94          StatusMessage msg = (StatusMessage)PortletMessaging.consume(request, PortletApplicationResources.TOPIC_PORTLET_SELECTOR, PortletApplicationResources.MESSAGE_STATUS);
95          if (msg != null)
96          {
97              this.getContext(request).put("statusMsg", msg);            
98          }
99          
100         String filtered = (String)PortletMessaging.receive(request, PortletApplicationResources.TOPIC_PORTLET_SELECTOR, PortletApplicationResources.MESSAGE_FILTERED);
101         if (filtered != null)
102         {
103             this.getContext(request).put(FILTERED, "on");            
104         }
105         
106         String searchString = (String)PortletMessaging.receive(request, PortletApplicationResources.TOPIC_PORTLET_SELECTOR, PortletApplicationResources.MESSAGE_SEARCHSTRING);
107         if (searchString != null)
108         {
109             this.getContext(request).put(SEARCH_STRING, searchString);            
110         }
111         
112         Set selectedCheckBoxes = (Set) PortletMessaging.receive(request, PortletApplicationResources.TOPIC_PORTLET_SELECTOR, PortletApplicationResources.MESSAGE_SELECTED);
113         if(selectedCheckBoxes == null) {
114             selectedCheckBoxes = new HashSet();
115         }
116         this.getContext(request).put("selectedPortlets",selectedCheckBoxes);
117         String selectedPortletsString = getAsString(selectedCheckBoxes);
118         this.getContext(request).put("selectedPortletsString", selectedPortletsString);
119         
120         super.doView(request, response);
121     }
122 
123     private String getAsString(Set s) 
124     {
125         StringBuffer sb = new StringBuffer();
126         if(s != null) 
127         {
128             Iterator it = s.iterator();
129             while(it.hasNext()) 
130             {
131                 String portletName = (String) it.next();
132                 if(sb.length() > 0) {
133                     sb.append(",");
134                 }
135                 sb.append("box_"+portletName);
136             }
137         }
138         return sb.toString();
139     }
140     
141     private Set getCheckBoxSet(ActionRequest request) {
142         Set s = new HashSet();
143         String checkBoxesString =  request.getParameter(CHECKEDSET);
144         StringTokenizer st = new StringTokenizer(checkBoxesString,",");
145         while(st.hasMoreTokens() ) 
146         {
147             String checkBox = st.nextToken();
148             if(checkBox.startsWith("box_")) {
149                 String portletName = checkBox.substring(4);
150                 s.add(portletName);
151             } else {
152                 s.add(checkBox);
153             }
154         }
155         // wait we need to subtracted the unchecked stuff
156         String unCheckBoxesString =  request.getParameter(UNCHECKEDSET);
157         StringTokenizer st2 = new StringTokenizer(unCheckBoxesString,",");
158         Set uns = new HashSet();
159         while(st2.hasMoreTokens() ) 
160         {
161             String checkBox = st2.nextToken();
162             if(checkBox.startsWith("box_")) {
163                 String portletName = checkBox.substring(4);
164                 uns.add(portletName);
165             } else {
166                 uns.add(checkBox);
167             }
168         }
169         // here's the actual removal
170         s.removeAll(uns);
171         
172         return s;
173     }
174     public void processAction(ActionRequest request, ActionResponse response)
175     throws PortletException, IOException
176     {
177         String filtered = request.getParameter(FILTERED);
178         
179         Set checkBoxes = getCheckBoxSet(request);
180         PortletMessaging.publish(request, PortletApplicationResources.TOPIC_PORTLET_SELECTOR, PortletApplicationResources.MESSAGE_SELECTED, checkBoxes);            
181         
182         String searchString = request.getParameter(SEARCH_STRING);
183         // huh, apparently this messaging API won't basically take a null and assume that's equivalent to a cancel.  In fact the null won't even
184         // overwrite the previous value.. it does nothing...
185         // So, we'll write some extra code to get around that
186         if((searchString != null) && (searchString.trim().length() > 0) )
187         {
188             PortletMessaging.publish(request, PortletApplicationResources.TOPIC_PORTLET_SELECTOR, PortletApplicationResources.MESSAGE_SEARCHSTRING, searchString);
189         } else
190         {
191             PortletMessaging.cancel(request, PortletApplicationResources.TOPIC_PORTLET_SELECTOR, PortletApplicationResources.MESSAGE_SEARCHSTRING);
192         }
193         
194         // if the filter parameter is non null AND also has some real chars... then we'll be filtered.
195         // otherwise assume no filter
196         if ((filtered != null) && (filtered.trim().length() > 0) )
197         {
198             PortletMessaging.publish(request, PortletApplicationResources.TOPIC_PORTLET_SELECTOR, PortletApplicationResources.MESSAGE_FILTERED, "on");            
199         }
200         else
201         {
202             PortletMessaging.cancel(request, PortletApplicationResources.TOPIC_PORTLET_SELECTOR, PortletApplicationResources.MESSAGE_FILTERED);
203         }
204         
205         super.processAction(request, response);
206             
207     }
208     
209     public void getRows(RenderRequest request, String sql, int windowSize)
210     throws Exception
211     {
212         getRows(request, sql, windowSize, null);
213     }
214 
215     public void getRows(RenderRequest request, String sql, int windowSize, String filter)
216     throws Exception    
217     {
218         List resultSetTitleList = new ArrayList();
219         List resultSetTypeList = new ArrayList();
220         try
221         {
222             Iterator portlets = null;
223             
224             if (filter == null)
225                 portlets = registry.getAllPortletDefinitions().iterator();
226             else
227                 portlets = searchEngine.search(filter).getResults().iterator();
228                                     
229             resultSetTypeList.add(String.valueOf(Types.VARCHAR));
230             resultSetTitleList.add("Portlet");
231             resultSetTitleList.add("Description");            
232             Locale locale = request.getLocale();
233             List list = new ArrayList();
234             
235             while (portlets.hasNext())
236             {
237                 PortletDefinitionComposite portlet = null;
238                 if (filter == null)
239                     portlet = (PortletDefinitionComposite)portlets.next();
240                 else
241                     portlet = this.getPortletFromParsedObject((ParsedObject)portlets.next());
242                 
243                 if (portlet == null)
244                     continue;
245                 
246                 // Do not display Jetspeed Layout Applications
247                 MutablePortletApplication pa = (MutablePortletApplication)portlet.getPortletApplicationDefinition();
248                 if (pa.isLayoutApplication())
249                     continue;
250                          
251                 // SECURITY filtering
252                 String uniqueName = pa.getName() + "::" + portlet.getName();
253                 if (securityAccessController.checkPortletAccess(portlet, JetspeedActions.MASK_VIEW))
254                 {
255                     String name = portlet.getDisplayNameText(locale);
256                     if (name == null)
257                     {
258                         name = portlet.getName();
259                     }
260                     list.add(new PortletInfo(uniqueName, name, portlet.getDescriptionText(locale)));
261                 }
262             }            
263             BrowserIterator iterator = new PortletIterator(
264                     list, resultSetTitleList, resultSetTypeList,
265                     windowSize);
266             setBrowserIterator(request, iterator);
267             iterator.sort("Portlet");
268         }
269         catch (Exception e)
270         {
271             //log.error("Exception in CMSBrowserAction.getRows: ", e);
272             e.printStackTrace();
273             throw e;
274         }        
275     }
276       
277     public int find(BrowserIterator iterator, String searchString, String searchColumn)
278     {
279         int index = 0;
280         
281         Iterator it = iterator.getResultSet().iterator();
282         while (it.hasNext())
283         {
284             PortletInfo info = (PortletInfo)it.next();
285             String name = info.getDisplayName();
286             if (name != null && name.startsWith(searchString))
287             {
288                 return index;
289             }
290             index++;
291         }
292         
293         return -1;
294     }
295     
296     protected PortletDefinitionComposite getPortletFromParsedObject(ParsedObject po)
297     {
298         boolean found = false;
299         String name = "";
300         Map fields = po.getFields();
301         if(fields != null)
302         {
303             Object id = fields.get("ID");
304     
305             if(id != null)
306             {
307                 if(id instanceof Collection)
308                 {
309                     Collection coll = (Collection)id;
310                     name = (String) coll.iterator().next();
311                 }
312                 else
313                 {
314                     name = (String)id;
315                 }
316             }
317             
318             if(po.getType().equals("portlet"))
319             {
320                 Object pa = fields.get("portlet_application");
321                 String paName = "";
322                 if(pa != null)
323                 {
324                     if(id instanceof Collection)
325                     {
326                         Collection coll = (Collection)pa;
327                         paName = (String) coll.iterator().next();
328                     }
329                     else
330                     {
331                         paName = (String)pa;
332                     }
333                 }
334                 name = paName + "::" + name;
335                 found = true;
336             }
337         }
338         if (found == false)
339             return null;
340         
341         return registry.getPortletDefinitionByUniqueName(name);
342     }
343 }