001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.util.bridges.alloy;
016    
017    import com.liferay.counter.service.CounterLocalServiceUtil;
018    import com.liferay.portal.kernel.bean.BeanPropertiesUtil;
019    import com.liferay.portal.kernel.bean.ConstantsBeanFactoryUtil;
020    import com.liferay.portal.kernel.dao.search.SearchContainer;
021    import com.liferay.portal.kernel.language.LanguageUtil;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.messaging.Destination;
025    import com.liferay.portal.kernel.messaging.InvokerMessageListener;
026    import com.liferay.portal.kernel.messaging.MessageBus;
027    import com.liferay.portal.kernel.messaging.MessageBusUtil;
028    import com.liferay.portal.kernel.messaging.MessageListener;
029    import com.liferay.portal.kernel.messaging.SerialDestination;
030    import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
031    import com.liferay.portal.kernel.portlet.LiferayPortletResponse;
032    import com.liferay.portal.kernel.portlet.PortletBag;
033    import com.liferay.portal.kernel.portlet.PortletBagPool;
034    import com.liferay.portal.kernel.portlet.PortletResponseUtil;
035    import com.liferay.portal.kernel.scheduler.CronText;
036    import com.liferay.portal.kernel.scheduler.CronTrigger;
037    import com.liferay.portal.kernel.scheduler.SchedulerEngineHelperUtil;
038    import com.liferay.portal.kernel.scheduler.StorageType;
039    import com.liferay.portal.kernel.scheduler.Trigger;
040    import com.liferay.portal.kernel.search.Hits;
041    import com.liferay.portal.kernel.search.Indexer;
042    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
043    import com.liferay.portal.kernel.search.SearchContext;
044    import com.liferay.portal.kernel.search.SearchContextFactory;
045    import com.liferay.portal.kernel.search.Sort;
046    import com.liferay.portal.kernel.servlet.ServletResponseUtil;
047    import com.liferay.portal.kernel.servlet.SessionMessages;
048    import com.liferay.portal.kernel.transaction.Isolation;
049    import com.liferay.portal.kernel.transaction.Propagation;
050    import com.liferay.portal.kernel.transaction.Transactional;
051    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
052    import com.liferay.portal.kernel.util.ContentTypes;
053    import com.liferay.portal.kernel.util.GetterUtil;
054    import com.liferay.portal.kernel.util.JavaConstants;
055    import com.liferay.portal.kernel.util.ParamUtil;
056    import com.liferay.portal.kernel.util.ServiceBeanMethodInvocationFactoryUtil;
057    import com.liferay.portal.kernel.util.StringBundler;
058    import com.liferay.portal.kernel.util.StringPool;
059    import com.liferay.portal.kernel.util.Validator;
060    import com.liferay.portal.kernel.util.WebKeys;
061    import com.liferay.portal.model.AttachedModel;
062    import com.liferay.portal.model.AuditedModel;
063    import com.liferay.portal.model.BaseModel;
064    import com.liferay.portal.model.Company;
065    import com.liferay.portal.model.GroupedModel;
066    import com.liferay.portal.model.PersistedModel;
067    import com.liferay.portal.model.Portlet;
068    import com.liferay.portal.model.User;
069    import com.liferay.portal.theme.ThemeDisplay;
070    import com.liferay.portal.util.PortalUtil;
071    
072    import java.io.Serializable;
073    
074    import java.lang.reflect.Method;
075    
076    import java.util.Date;
077    import java.util.HashMap;
078    import java.util.List;
079    import java.util.Locale;
080    import java.util.Map;
081    import java.util.Set;
082    
083    import javax.portlet.ActionRequest;
084    import javax.portlet.ActionResponse;
085    import javax.portlet.EventRequest;
086    import javax.portlet.EventResponse;
087    import javax.portlet.MimeResponse;
088    import javax.portlet.PortletContext;
089    import javax.portlet.PortletRequest;
090    import javax.portlet.PortletRequestDispatcher;
091    import javax.portlet.PortletResponse;
092    import javax.portlet.PortletURL;
093    import javax.portlet.RenderRequest;
094    import javax.portlet.RenderResponse;
095    import javax.portlet.ResourceRequest;
096    import javax.portlet.ResourceResponse;
097    
098    import javax.servlet.ServletConfig;
099    import javax.servlet.ServletContext;
100    import javax.servlet.http.HttpServletRequest;
101    import javax.servlet.http.HttpServletResponse;
102    import javax.servlet.jsp.PageContext;
103    
104    /**
105     * @author Brian Wing Shun Chan
106     */
107    public abstract class BaseAlloyControllerImpl implements AlloyController {
108    
109            public static final String TOUCH =
110                    BaseAlloyControllerImpl.class.getName() + "#TOUCH#";
111    
112            public void afterPropertiesSet() {
113                    initClass();
114                    initServletVariables();
115                    initPortletVariables();
116                    initThemeDisplayVariables();
117                    initMethods();
118                    initPaths();
119                    initIndexer();
120                    initScheduler();
121            }
122    
123            public void execute() throws Exception {
124                    Method method = getMethod(actionPath);
125    
126                    if (method == null) {
127                            if (log.isDebugEnabled()) {
128                                    log.debug("No method found for action " + actionPath);
129                            }
130                    }
131    
132                    if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
133                            Class<?> superClass = clazz.getSuperclass();
134    
135                            Method executeActionMethod = superClass.getDeclaredMethod(
136                                    "executeAction", new Class<?>[] {Method.class});
137    
138                            ServiceBeanMethodInvocationFactoryUtil.proceed(
139                                    this, BaseAlloyControllerImpl.class, executeActionMethod,
140                                    new Object[] {method}, new String[] {"transactionAdvice"});
141                    }
142                    else if (lifecycle.equals(PortletRequest.RENDER_PHASE)) {
143                            executeRender(method);
144                    }
145                    else if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
146                            executeResource(method);
147                    }
148            }
149    
150            public ThemeDisplay getThemeDisplay() {
151                    return themeDisplay;
152            }
153    
154            public long increment() throws Exception {
155                    return CounterLocalServiceUtil.increment();
156            }
157    
158            public void setPageContext(PageContext pageContext) {
159                    this.pageContext = pageContext;
160            }
161    
162            public void updateModel(BaseModel<?> baseModel) throws Exception {
163                    BeanPropertiesUtil.setProperties(baseModel, request);
164    
165                    if (baseModel.isNew()) {
166                            baseModel.setPrimaryKeyObj(increment());
167                    }
168    
169                    updateAuditedModel(baseModel);
170                    updateGroupedModel(baseModel);
171                    updateAttachedModel(baseModel);
172    
173                    if (baseModel instanceof PersistedModel) {
174                            PersistedModel persistedModel = (PersistedModel)baseModel;
175    
176                            persistedModel.persist();
177                    }
178    
179                    if ((indexer != null) &&
180                            indexerClassName.equals(baseModel.getModelClassName())) {
181    
182                            indexer.reindex(baseModel);
183                    }
184            }
185    
186            protected void addSuccessMessage() {
187                    String successMessage = ParamUtil.getString(
188                            portletRequest, "successMessage");
189    
190                    SessionMessages.add(portletRequest, "requestProcessed", successMessage);
191            }
192    
193            protected String buildIncludePath(String viewPath) {
194                    if (viewPath.equals(_VIEW_PATH_ERROR)) {
195                            return "/WEB-INF/jsp/".concat(
196                                    portlet.getFriendlyURLMapping()).concat("/views/error.jsp");
197                    }
198    
199                    StringBundler sb = new StringBundler(7);
200    
201                    sb.append("/WEB-INF/jsp/");
202                    sb.append(portlet.getFriendlyURLMapping());
203                    sb.append("/views/");
204                    sb.append(controllerPath);
205                    sb.append(StringPool.SLASH);
206                    sb.append(viewPath);
207                    sb.append(".jsp");
208    
209                    return sb.toString();
210            }
211    
212            protected Indexer buildIndexer() {
213                    return null;
214            }
215    
216            protected MessageListener buildSchedulerMessageListener() {
217                    return null;
218            }
219    
220            @Transactional(
221                    isolation = Isolation.PORTAL, propagation = Propagation.REQUIRES_NEW,
222                    rollbackFor = {Exception.class}
223            )
224            protected void executeAction(Method method) throws Exception {
225                    if (method != null) {
226                            method.invoke(this);
227                    }
228    
229                    actionRequest.setAttribute(
230                            CALLED_PROCESS_ACTION, Boolean.TRUE.toString());
231    
232                    if (Validator.isNotNull(viewPath)) {
233                            actionRequest.setAttribute(VIEW_PATH, viewPath);
234    
235                            PortalUtil.copyRequestParameters(actionRequest, actionResponse);
236                    }
237                    else if (Validator.isNotNull(redirect)) {
238                            actionResponse.sendRedirect(redirect);
239                    }
240            }
241    
242            protected void executeRender(Method method) throws Exception {
243                    boolean calledProcessAction = GetterUtil.getBoolean(
244                            (String)request.getAttribute(CALLED_PROCESS_ACTION));
245    
246                    if (!calledProcessAction) {
247                            if (method != null) {
248                                    method.invoke(this);
249                            }
250                    }
251    
252                    if (Validator.isNull(viewPath)) {
253                            viewPath = actionPath;
254                    }
255    
256                    String includePath = buildIncludePath(viewPath);
257    
258                    PortletRequestDispatcher portletRequestDispatcher =
259                            portletContext.getRequestDispatcher(includePath);
260    
261                    if (portletRequestDispatcher == null) {
262                            log.error(includePath + " is not a valid include");
263                    }
264                    else {
265                            portletRequestDispatcher.include(portletRequest, portletResponse);
266                    }
267    
268                    Boolean touch = (Boolean)portletContext.getAttribute(
269                            TOUCH + portlet.getRootPortletId());
270    
271                    if (touch == null) {
272                            String touchPath =
273                                    "/WEB-INF/jsp/" + portlet.getFriendlyURLMapping() +
274                                            "/views/touch.jsp";
275    
276                            if (log.isDebugEnabled()) {
277                                    log.debug(
278                                            "Touch " + portlet.getRootPortletId() + " by including " +
279                                                    touchPath);
280                            }
281    
282                            portletContext.setAttribute(
283                                    TOUCH + portlet.getRootPortletId(), Boolean.FALSE);
284    
285                            portletRequestDispatcher = portletContext.getRequestDispatcher(
286                                    touchPath);
287    
288                            if (portletRequestDispatcher != null) {
289                                    portletRequestDispatcher.include(
290                                            portletRequest, portletResponse);
291                            }
292                    }
293            }
294    
295            protected void executeResource(Method method) throws Exception {
296                    if (method != null) {
297                            method.invoke(this);
298                    }
299            }
300    
301            protected Object getConstantsBean(Class<?> clazz) {
302                    return ConstantsBeanFactoryUtil.getConstantsBean(clazz);
303            }
304    
305            protected Method getMethod(String methodName, Class<?>... parameterTypes) {
306                    String methodKey = getMethodKey(methodName, parameterTypes);
307    
308                    return methodsMap.get(methodKey);
309            }
310    
311            protected String getMethodKey(
312                    String methodName, Class<?>... parameterTypes) {
313    
314                    StringBundler sb = new StringBundler(parameterTypes.length * 2 + 2);
315    
316                    sb.append(methodName);
317                    sb.append(StringPool.POUND);
318    
319                    for (Class<?> parameterType : parameterTypes) {
320                            sb.append(parameterType.getName());
321                            sb.append(StringPool.POUND);
322                    }
323    
324                    return sb.toString();
325            }
326    
327            protected String getSchedulerDestinationName() {
328                    return "liferay/alloy/".concat(getSchedulerGroupName());
329            }
330    
331            protected String getSchedulerGroupName() {
332                    String rootPortletId = portlet.getRootPortletId();
333    
334                    return rootPortletId.concat(StringPool.SLASH).concat(controllerPath);
335            }
336    
337            protected String getSchedulerJobName() {
338                    return getSchedulerGroupName();
339            }
340    
341            protected Trigger getSchedulerTrigger() {
342                    CronText cronText = new CronText(
343                            CalendarFactoryUtil.getCalendar(), CronText.DAILY_FREQUENCY, 1);
344    
345                    return new CronTrigger(
346                            getSchedulerJobName(), getSchedulerGroupName(),
347                            cronText.toString());
348            }
349    
350            protected Map<String, Serializable> getSearchAttributes(
351                            Object... attributes)
352                    throws Exception {
353    
354                    Map<String, Serializable> attributesMap =
355                            new HashMap<String, Serializable>();
356    
357                    if ((attributes.length == 0) || ((attributes.length % 2) != 0)) {
358                            throw new Exception("Arguments length is not an even number");
359                    }
360    
361                    for (int i = 0; i < attributes.length; i += 2) {
362                            String name = String.valueOf(attributes[i]);
363    
364                            Serializable value = (Serializable)attributes[i + 1];
365    
366                            attributesMap.put(name, value);
367                    }
368    
369                    return attributesMap;
370            }
371    
372            protected long increment(String name) throws Exception {
373                    return CounterLocalServiceUtil.increment(name);
374            }
375    
376            protected void initClass() {
377                    clazz = getClass();
378                    classLoader = clazz.getClassLoader();
379            }
380    
381            protected void initIndexer() {
382                    indexer = buildIndexer();
383    
384                    if (indexer == null) {
385                            return;
386                    }
387    
388                    indexerClassName = indexer.getClassNames()[0];
389    
390                    Indexer existingIndexer = IndexerRegistryUtil.getIndexer(
391                            indexerClassName);
392    
393                    if ((existingIndexer != null) && (existingIndexer == indexer)) {
394                            BaseAlloyIndexer baseAlloyIndexer = (BaseAlloyIndexer)indexer;
395    
396                            alloyServiceInvoker = baseAlloyIndexer.getAlloyServiceInvoker();
397    
398                            return;
399                    }
400    
401                    alloyServiceInvoker = new AlloyServiceInvoker(indexerClassName);
402    
403                    BaseAlloyIndexer baseAlloyIndexer = (BaseAlloyIndexer)indexer;
404    
405                    baseAlloyIndexer.setAlloyServiceInvoker(alloyServiceInvoker);
406                    baseAlloyIndexer.setPortletId(portlet.getRootPortletId());
407    
408                    PortletBag portletBag = PortletBagPool.get(portlet.getPortletId());
409    
410                    List<Indexer> indexerInstances = portletBag.getIndexerInstances();
411    
412                    if (existingIndexer != null) {
413                            IndexerRegistryUtil.unregister(existingIndexer);
414    
415                            indexerInstances.remove(existingIndexer);
416                    }
417    
418                    IndexerRegistryUtil.register(indexer);
419    
420                    indexerInstances.add(indexer);
421            }
422    
423            protected void initMethods() {
424                    methodsMap = new HashMap<String, Method>();
425    
426                    Method[] methods = clazz.getMethods();
427    
428                    for (Method method : methods) {
429                            String methodKey = getMethodKey(
430                                    method.getName(), method.getParameterTypes());
431    
432                            methodsMap.put(methodKey, method);
433                    }
434            }
435    
436            protected void initPaths() {
437                    controllerPath = ParamUtil.getString(request, "controller");
438    
439                    if (Validator.isNull(controllerPath)) {
440                            Map<String, String> defaultRouteParameters =
441                                    alloyPortlet.getDefaultRouteParameters();
442    
443                            controllerPath = defaultRouteParameters.get("controller");
444                    }
445    
446                    if (log.isDebugEnabled()) {
447                            log.debug("Controller path " + controllerPath);
448                    }
449    
450                    actionPath = ParamUtil.getString(request, "action");
451    
452                    if (Validator.isNull(actionPath)) {
453                            Map<String, String> defaultRouteParameters =
454                                    alloyPortlet.getDefaultRouteParameters();
455    
456                            actionPath = defaultRouteParameters.get("action");
457                    }
458    
459                    if (log.isDebugEnabled()) {
460                            log.debug("Action path " + actionPath);
461                    }
462    
463                    viewPath = GetterUtil.getString(
464                            (String)request.getAttribute(VIEW_PATH));
465    
466                    request.removeAttribute(VIEW_PATH);
467    
468                    if (log.isDebugEnabled()) {
469                            log.debug("View path " + viewPath);
470                    }
471    
472                    if (mimeResponse != null) {
473                            portletURL = mimeResponse.createRenderURL();
474    
475                            portletURL.setParameter("action", actionPath);
476                            portletURL.setParameter("controller", controllerPath);
477                            portletURL.setParameter("format", "html");
478    
479                            if (log.isDebugEnabled()) {
480                                    log.debug("Portlet URL " + portletURL);
481                            }
482                    }
483            }
484    
485            protected void initPortletVariables() {
486                    liferayPortletConfig = (LiferayPortletConfig)request.getAttribute(
487                            JavaConstants.JAVAX_PORTLET_CONFIG);
488    
489                    portletContext = liferayPortletConfig.getPortletContext();
490    
491                    portlet = liferayPortletConfig.getPortlet();
492    
493                    alloyPortlet = (AlloyPortlet)request.getAttribute(
494                            JavaConstants.JAVAX_PORTLET_PORTLET);
495    
496                    alloyPortlet.registerAlloyController(this);
497    
498                    portletRequest = (PortletRequest)request.getAttribute(
499                            JavaConstants.JAVAX_PORTLET_REQUEST);
500                    portletResponse = (PortletResponse)request.getAttribute(
501                            JavaConstants.JAVAX_PORTLET_RESPONSE);
502    
503                    liferayPortletResponse = (LiferayPortletResponse)portletResponse;
504    
505                    lifecycle = GetterUtil.getString(
506                            (String)request.getAttribute(PortletRequest.LIFECYCLE_PHASE));
507    
508                    if (log.isDebugEnabled()) {
509                            log.debug("Lifecycle " + lifecycle);
510                    }
511    
512                    if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
513                            actionRequest = (ActionRequest)portletRequest;
514                            actionResponse = (ActionResponse)portletResponse;
515                    }
516                    else if (lifecycle.equals(PortletRequest.EVENT_PHASE)) {
517                            eventRequest = (EventRequest)portletRequest;
518                            eventResponse = (EventResponse)portletResponse;
519                    }
520                    else if (lifecycle.equals(PortletRequest.RENDER_PHASE)) {
521                            mimeResponse = (MimeResponse)portletResponse;
522                            renderRequest = (RenderRequest)portletRequest;
523                            renderResponse = (RenderResponse)portletResponse;
524                    }
525                    else if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
526                            mimeResponse = (MimeResponse)portletResponse;
527                            resourceRequest = (ResourceRequest)portletRequest;
528                            resourceResponse = (ResourceResponse)portletResponse;
529                    }
530            }
531    
532            protected void initScheduler() {
533                    schedulerMessageListener = buildSchedulerMessageListener();
534    
535                    if (schedulerMessageListener == null) {
536                            return;
537                    }
538    
539                    MessageBus messageBus = MessageBusUtil.getMessageBus();
540    
541                    Destination destination = messageBus.getDestination(
542                            getSchedulerDestinationName());
543    
544                    if (destination != null) {
545                            Set<MessageListener> messageListeners =
546                                    destination.getMessageListeners();
547    
548                            for (MessageListener messageListener : messageListeners) {
549                                    if (!(messageListener instanceof InvokerMessageListener)) {
550                                            continue;
551                                    }
552    
553                                    InvokerMessageListener invokerMessageListener =
554                                            (InvokerMessageListener)messageListener;
555    
556                                    messageListener = invokerMessageListener.getMessageListener();
557    
558                                    if (schedulerMessageListener == messageListener) {
559                                            return;
560                                    }
561    
562                                    Class<?> schedulerMessageListenerClass =
563                                            schedulerMessageListener.getClass();
564    
565                                    String schedulerMessageListenerClassName =
566                                            schedulerMessageListenerClass.getName();
567    
568                                    Class<?> messageListenerClass = messageListener.getClass();
569    
570                                    if (!schedulerMessageListenerClassName.equals(
571                                                    messageListenerClass.getName())) {
572    
573                                            continue;
574                                    }
575    
576                                    try {
577                                            SchedulerEngineHelperUtil.unschedule(
578                                                    getSchedulerJobName(), getSchedulerGroupName(),
579                                                    StorageType.MEMORY_CLUSTERED);
580    
581                                            MessageBusUtil.unregisterMessageListener(
582                                                    getSchedulerDestinationName(), messageListener);
583                                    }
584                                    catch (Exception e) {
585                                            log.error(e, e);
586                                    }
587    
588                                    break;
589                            }
590                    }
591                    else {
592                            SerialDestination serialDestination = new SerialDestination();
593    
594                            serialDestination.setName(getSchedulerDestinationName());
595    
596                            serialDestination.open();
597    
598                            MessageBusUtil.addDestination(serialDestination);
599                    }
600    
601                    try {
602                            MessageBusUtil.registerMessageListener(
603                                    getSchedulerDestinationName(), schedulerMessageListener);
604    
605                            SchedulerEngineHelperUtil.schedule(
606                                    getSchedulerTrigger(), StorageType.MEMORY_CLUSTERED, null,
607                                    getSchedulerDestinationName(), null, 0);
608                    }
609                    catch (Exception e) {
610                            log.error(e, e);
611                    }
612            }
613    
614            protected void initServletVariables() {
615                    servletConfig = pageContext.getServletConfig();
616                    servletContext = pageContext.getServletContext();
617                    request = (HttpServletRequest)pageContext.getRequest();
618                    response = (HttpServletResponse)pageContext.getResponse();
619            }
620    
621            protected void initThemeDisplayVariables() {
622                    themeDisplay = (ThemeDisplay)request.getAttribute(
623                            WebKeys.THEME_DISPLAY);
624    
625                    company = themeDisplay.getCompany();
626                    locale = themeDisplay.getLocale();
627                    user = themeDisplay.getUser();
628            }
629    
630            protected void redirectTo(PortletURL portletURL) {
631                    redirectTo(portletURL.toString());
632            }
633    
634            protected void redirectTo(String redirect) {
635                    if (!lifecycle.equals(PortletRequest.ACTION_PHASE)) {
636                            throw new IllegalArgumentException(
637                                    "redirectTo can only be called during the action phase");
638                    }
639    
640                    if (Validator.isNotNull(viewPath)) {
641                            throw new IllegalArgumentException(
642                                    "redirectTo cannot be called if render has been called");
643                    }
644    
645                    this.redirect = redirect;
646            }
647    
648            protected void render(String actionPath) {
649                    if (Validator.isNotNull(redirect)) {
650                            throw new IllegalArgumentException(
651                                    "render cannot be called if redirectTo has been called");
652                    }
653    
654                    viewPath = actionPath;
655            }
656    
657            protected void renderError(String pattern, Object... arguments) {
658                    portletRequest.setAttribute("arguments", arguments);
659                    portletRequest.setAttribute("pattern", pattern);
660    
661                    render(_VIEW_PATH_ERROR);
662            }
663    
664            protected AlloySearchResult search(
665                            Map<String, Serializable> attributes, String keywords, Sort sort)
666                    throws Exception {
667    
668                    return search(attributes, keywords, new Sort[] {sort});
669            }
670    
671            protected AlloySearchResult search(
672                            Map<String, Serializable> attributes, String keywords, Sort[] sorts)
673                    throws Exception {
674    
675                    if (indexer == null) {
676                            throw new Exception("No indexer found for " + controllerPath);
677                    }
678    
679                    AlloySearchResult alloySearchResult = new AlloySearchResult();
680    
681                    alloySearchResult.setAlloyServiceInvoker(alloyServiceInvoker);
682    
683                    SearchContainer<BaseModel<?>> searchContainer =
684                            new SearchContainer<BaseModel<?>>(
685                                    portletRequest, portletURL, null, null);
686    
687                    SearchContext searchContext = SearchContextFactory.getInstance(request);
688    
689                    if ((attributes != null) && !attributes.isEmpty()) {
690                            searchContext.setAttributes(attributes);
691                    }
692    
693                    searchContext.setEnd(searchContainer.getEnd());
694    
695                    if (Validator.isNotNull(keywords)) {
696                            searchContext.setKeywords(keywords);
697                    }
698    
699                    if ((sorts != null) && (sorts.length > 0)) {
700                            searchContext.setSorts(sorts);
701                    }
702    
703                    searchContext.setStart(searchContainer.getStart());
704    
705                    Hits hits = indexer.search(searchContext);
706    
707                    alloySearchResult.setHits(hits);
708    
709                    alloySearchResult.setPortletURL(portletURL);
710    
711                    alloySearchResult.afterPropertiesSet();
712    
713                    return alloySearchResult;
714            }
715    
716            protected AlloySearchResult search(String keywords) throws Exception {
717                    return search(keywords, (Sort[])null);
718            }
719    
720            protected AlloySearchResult search(String keywords, Sort sort)
721                    throws Exception {
722    
723                    return search(keywords, new Sort[] {sort});
724            }
725    
726            protected AlloySearchResult search(String keywords, Sort[] sorts)
727                    throws Exception {
728    
729                    return search(null, keywords, sorts);
730            }
731    
732            protected String translate(String pattern, Object... arguments) {
733                    return LanguageUtil.format(locale, pattern, arguments);
734            }
735    
736            protected void updateAttachedModel(BaseModel<?> baseModel)
737                    throws Exception {
738    
739                    if (!(baseModel instanceof AttachedModel)) {
740                            return;
741                    }
742    
743                    AttachedModel attachedModel = (AttachedModel)baseModel;
744    
745                    long classNameId = 0;
746    
747                    String className = ParamUtil.getString(request, "className");
748    
749                    if (Validator.isNotNull(className)) {
750                            classNameId = PortalUtil.getClassNameId(className);
751                    }
752    
753                    if (classNameId > 0) {
754                            attachedModel.setClassNameId(classNameId);
755                    }
756    
757                    long classPK = ParamUtil.getLong(request, "classPK");
758    
759                    if (classPK > 0) {
760                            attachedModel.setClassPK(classPK);
761                    }
762            }
763    
764            protected void updateAuditedModel(BaseModel<?> baseModel) throws Exception {
765                    if (!(baseModel instanceof AuditedModel)) {
766                            return;
767                    }
768    
769                    AuditedModel auditedModel = (AuditedModel)baseModel;
770    
771                    if (baseModel.isNew()) {
772                            auditedModel.setCompanyId(company.getCompanyId());
773                            auditedModel.setUserId(user.getUserId());
774                            auditedModel.setUserName(user.getFullName());
775                            auditedModel.setCreateDate(new Date());
776                            auditedModel.setModifiedDate(auditedModel.getCreateDate());
777                    }
778                    else {
779                            auditedModel.setModifiedDate(new Date());
780                    }
781            }
782    
783            protected void updateGroupedModel(BaseModel<?> baseModel) throws Exception {
784                    if (!(baseModel instanceof GroupedModel) || !baseModel.isNew()) {
785                            return;
786                    }
787    
788                    GroupedModel groupedModel = (GroupedModel)baseModel;
789    
790                    groupedModel.setGroupId(themeDisplay.getScopeGroupId());
791            }
792    
793            protected void writeJSON(Object json) throws Exception {
794                    if (actionResponse != null) {
795                            HttpServletResponse response = PortalUtil.getHttpServletResponse(
796                                    actionResponse);
797    
798                            response.setContentType(ContentTypes.APPLICATION_JSON);
799    
800                            ServletResponseUtil.write(response, json.toString());
801                    }
802                    else if (mimeResponse != null) {
803                            mimeResponse.setContentType(ContentTypes.APPLICATION_JSON);
804    
805                            PortletResponseUtil.write(mimeResponse, json.toString());
806                    }
807            }
808    
809            protected static final String CALLED_PROCESS_ACTION =
810                    BaseAlloyControllerImpl.class.getName() + "#CALLED_PROCESS_ACTION";
811    
812            protected static final String VIEW_PATH =
813                    BaseAlloyControllerImpl.class.getName() + "#VIEW_PATH";
814    
815            protected static Log log = LogFactoryUtil.getLog(
816                    BaseAlloyControllerImpl.class);
817    
818            protected String actionPath;
819            protected ActionRequest actionRequest;
820            protected ActionResponse actionResponse;
821            protected AlloyPortlet alloyPortlet;
822            protected AlloyServiceInvoker alloyServiceInvoker;
823            protected ClassLoader classLoader;
824            protected Class<?> clazz;
825            protected Company company;
826            protected String controllerPath;
827            protected EventRequest eventRequest;
828            protected EventResponse eventResponse;
829            protected Indexer indexer;
830            protected String indexerClassName;
831            protected String lifecycle;
832            protected LiferayPortletConfig liferayPortletConfig;
833            protected LiferayPortletResponse liferayPortletResponse;
834            protected Locale locale;
835            protected Map<String, Method> methodsMap;
836            protected MimeResponse mimeResponse;
837            protected PageContext pageContext;
838            protected Portlet portlet;
839            protected PortletContext portletContext;
840            protected PortletRequest portletRequest;
841            protected PortletResponse portletResponse;
842            protected PortletURL portletURL;
843            protected String redirect;
844            protected RenderRequest renderRequest;
845            protected RenderResponse renderResponse;
846            protected HttpServletRequest request;
847            protected ResourceRequest resourceRequest;
848            protected ResourceResponse resourceResponse;
849            protected HttpServletResponse response;
850            protected MessageListener schedulerMessageListener;
851            protected ServletConfig servletConfig;
852            protected ServletContext servletContext;
853            protected ThemeDisplay themeDisplay;
854            protected User user;
855            protected String viewPath;
856    
857            private static final String _VIEW_PATH_ERROR = "VIEW_PATH_ERROR";
858    
859    }