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