001    /**
002     * Copyright (c) 2000-2012 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.portal.service.impl;
016    
017    import com.liferay.portal.AccountNameException;
018    import com.liferay.portal.CompanyMxException;
019    import com.liferay.portal.CompanyVirtualHostException;
020    import com.liferay.portal.CompanyWebIdException;
021    import com.liferay.portal.LocaleException;
022    import com.liferay.portal.NoSuchShardException;
023    import com.liferay.portal.NoSuchUserException;
024    import com.liferay.portal.NoSuchVirtualHostException;
025    import com.liferay.portal.kernel.exception.PortalException;
026    import com.liferay.portal.kernel.exception.SystemException;
027    import com.liferay.portal.kernel.language.LanguageUtil;
028    import com.liferay.portal.kernel.log.Log;
029    import com.liferay.portal.kernel.log.LogFactoryUtil;
030    import com.liferay.portal.kernel.search.FacetedSearcher;
031    import com.liferay.portal.kernel.search.Hits;
032    import com.liferay.portal.kernel.search.Indexer;
033    import com.liferay.portal.kernel.search.SearchContext;
034    import com.liferay.portal.kernel.search.SearchEngineUtil;
035    import com.liferay.portal.kernel.search.facet.AssetEntriesFacet;
036    import com.liferay.portal.kernel.search.facet.Facet;
037    import com.liferay.portal.kernel.search.facet.ScopeFacet;
038    import com.liferay.portal.kernel.util.ArrayUtil;
039    import com.liferay.portal.kernel.util.Base64;
040    import com.liferay.portal.kernel.util.LocaleUtil;
041    import com.liferay.portal.kernel.util.PropsKeys;
042    import com.liferay.portal.kernel.util.StringPool;
043    import com.liferay.portal.kernel.util.StringUtil;
044    import com.liferay.portal.kernel.util.TimeZoneUtil;
045    import com.liferay.portal.kernel.util.UnicodeProperties;
046    import com.liferay.portal.kernel.util.Validator;
047    import com.liferay.portal.kernel.workflow.WorkflowConstants;
048    import com.liferay.portal.model.Account;
049    import com.liferay.portal.model.Company;
050    import com.liferay.portal.model.CompanyConstants;
051    import com.liferay.portal.model.Contact;
052    import com.liferay.portal.model.ContactConstants;
053    import com.liferay.portal.model.Group;
054    import com.liferay.portal.model.Role;
055    import com.liferay.portal.model.RoleConstants;
056    import com.liferay.portal.model.User;
057    import com.liferay.portal.model.VirtualHost;
058    import com.liferay.portal.service.base.CompanyLocalServiceBaseImpl;
059    import com.liferay.portal.util.Portal;
060    import com.liferay.portal.util.PortalInstances;
061    import com.liferay.portal.util.PrefsPropsUtil;
062    import com.liferay.portal.util.PropsUtil;
063    import com.liferay.portal.util.PropsValues;
064    import com.liferay.util.Encryptor;
065    import com.liferay.util.EncryptorException;
066    
067    import java.io.File;
068    import java.io.IOException;
069    import java.io.InputStream;
070    
071    import java.util.ArrayList;
072    import java.util.Date;
073    import java.util.List;
074    import java.util.Locale;
075    import java.util.Map;
076    import java.util.TimeZone;
077    
078    import javax.portlet.PortletException;
079    import javax.portlet.PortletPreferences;
080    
081    /**
082     * The implementation of the company local service. Each company refers to a
083     * separate portal instance.
084     *
085     * @author Brian Wing Shun Chan
086     * @author Julio Camarero
087     */
088    public class CompanyLocalServiceImpl extends CompanyLocalServiceBaseImpl {
089    
090            /**
091             * Adds a company.
092             *
093             * @param  webId the the company's web domain
094             * @param  virtualHostname the company's virtual host name
095             * @param  mx the company's mail domain
096             * @param  shardName the company's shard
097             * @param  system whether the company is the very first company (i.e., the
098             *         super company)
099             * @param  maxUsers the max number of company users (optionally
100             *         <code>0</code>)
101             * @param  active whether the company is active
102             * @return the company
103             * @throws PortalException if the web domain, virtual host name, or mail
104             *         domain was invalid
105             * @throws SystemException if a system exception occurred
106             */
107            public Company addCompany(
108                            String webId, String virtualHostname, String mx, String shardName,
109                            boolean system, int maxUsers, boolean active)
110                    throws PortalException, SystemException {
111    
112                    // Company
113    
114                    virtualHostname = virtualHostname.trim().toLowerCase();
115    
116                    if (Validator.isNull(webId) ||
117                            webId.equals(PropsValues.COMPANY_DEFAULT_WEB_ID) ||
118                            (companyPersistence.fetchByWebId(webId) != null)) {
119    
120                            throw new CompanyWebIdException();
121                    }
122    
123                    validate(webId, virtualHostname, mx);
124    
125                    Company company = checkCompany(webId, mx, shardName);
126    
127                    company.setMx(mx);
128                    company.setSystem(system);
129                    company.setMaxUsers(maxUsers);
130                    company.setActive(active);
131    
132                    companyPersistence.update(company);
133    
134                    // Virtual host
135    
136                    updateVirtualHost(company.getCompanyId(), virtualHostname);
137    
138                    return company;
139            }
140    
141            /**
142             * Returns the company with the web domain.
143             *
144             * The method sets mail domain to the web domain, and the shard name to
145             * the default name set in portal.properties
146             *
147             * @param  webId the company's web domain
148             * @return the company with the web domain
149             * @throws PortalException if a portal exception occurred
150             * @throws SystemException if a system exception occurred
151             */
152            public Company checkCompany(String webId)
153                    throws PortalException, SystemException {
154    
155                    String mx = webId;
156    
157                    return companyLocalService.checkCompany(
158                            webId, mx, PropsValues.SHARD_DEFAULT_NAME);
159            }
160    
161            /**
162             * Returns the company with the web domain, mail domain, and shard. If no
163             * such company exits, the method will create a new company.
164             *
165             * The method goes through a series of checks to ensure that the company
166             * contains default users, groups, etc.
167             *
168             * @param  webId the company's web domain
169             * @param  mx the company's mail domain
170             * @param  shardName the company's shard
171             * @return the company with the web domain, mail domain, and shard
172             * @throws PortalException if a portal exception occurred
173             * @throws SystemException if a system exception occurred
174             */
175            public Company checkCompany(String webId, String mx, String shardName)
176                    throws PortalException, SystemException {
177    
178                    // Company
179    
180                    Date now = new Date();
181    
182                    Company company = companyPersistence.fetchByWebId(webId);
183    
184                    if (company == null) {
185                            String name = webId;
186                            String legalName = null;
187                            String legalId = null;
188                            String legalType = null;
189                            String sicCode = null;
190                            String tickerSymbol = null;
191                            String industry = null;
192                            String type = null;
193                            String size = null;
194    
195                            long companyId = counterLocalService.increment();
196    
197                            company = companyPersistence.create(companyId);
198    
199                            try {
200                                    company.setKey(Base64.objectToString(Encryptor.generateKey()));
201                            }
202                            catch (EncryptorException ee) {
203                                    throw new SystemException(ee);
204                            }
205    
206                            company.setWebId(webId);
207                            company.setMx(mx);
208                            company.setActive(true);
209    
210                            companyPersistence.update(company);
211    
212                            // Shard
213    
214                            shardLocalService.addShard(
215                                    Company.class.getName(), companyId, shardName);
216    
217                            // Account
218    
219                            updateAccount(
220                                    company, name, legalName, legalId, legalType, sicCode,
221                                    tickerSymbol, industry, type, size);
222    
223                            // Virtual host
224    
225                            if (webId.equals(PropsValues.COMPANY_DEFAULT_WEB_ID)) {
226                                    updateVirtualHost(companyId, _DEFAULT_VIRTUAL_HOST);
227                            }
228    
229                            // Demo settings
230    
231                            if (webId.equals("liferay.net")) {
232                                    company = companyPersistence.findByWebId(webId);
233    
234                                    updateVirtualHost(companyId, "demo.liferay.net");
235    
236                                    updateSecurity(
237                                            companyId, CompanyConstants.AUTH_TYPE_EA, true, true, true,
238                                            true, false, true);
239    
240                                    PortletPreferences preferences = PrefsPropsUtil.getPreferences(
241                                            companyId);
242    
243                                    try {
244                                            preferences.setValue(
245                                                    PropsKeys.ADMIN_EMAIL_FROM_NAME, "Liferay Demo");
246                                            preferences.setValue(
247                                                    PropsKeys.ADMIN_EMAIL_FROM_ADDRESS, "test@liferay.net");
248    
249                                            preferences.store();
250                                    }
251                                    catch (IOException ioe) {
252                                            throw new SystemException(ioe);
253                                    }
254                                    catch (PortletException pe) {
255                                            throw new SystemException(pe);
256                                    }
257                            }
258                    }
259                    else {
260                            try {
261                                    shardLocalService.getShard(
262                                            Company.class.getName(), company.getCompanyId());
263                            }
264                            catch (NoSuchShardException nsse) {
265                                    shardLocalService.addShard(
266                                            Company.class.getName(), company.getCompanyId(), shardName);
267                            }
268                    }
269    
270                    long companyId = company.getCompanyId();
271    
272                    // Key
273    
274                    checkCompanyKey(companyId);
275    
276                    // Default user
277    
278                    User defaultUser = null;
279    
280                    try {
281                            defaultUser = userLocalService.getDefaultUser(companyId);
282    
283                            if (!defaultUser.isAgreedToTermsOfUse()) {
284                                    defaultUser.setAgreedToTermsOfUse(true);
285    
286                                    userPersistence.update(defaultUser);
287                            }
288                    }
289                    catch (NoSuchUserException nsue) {
290                            long userId = counterLocalService.increment();
291    
292                            defaultUser = userPersistence.create(userId);
293    
294                            defaultUser.setCompanyId(companyId);
295                            defaultUser.setCreateDate(now);
296                            defaultUser.setModifiedDate(now);
297                            defaultUser.setDefaultUser(true);
298                            defaultUser.setContactId(counterLocalService.increment());
299                            defaultUser.setPassword("password");
300                            defaultUser.setScreenName(String.valueOf(defaultUser.getUserId()));
301                            defaultUser.setEmailAddress("default@" + company.getMx());
302    
303                            if (Validator.isNotNull(PropsValues.COMPANY_DEFAULT_LOCALE)) {
304                                    defaultUser.setLanguageId(PropsValues.COMPANY_DEFAULT_LOCALE);
305                            }
306                            else {
307                                    Locale locale = LocaleUtil.getDefault();
308    
309                                    defaultUser.setLanguageId(locale.toString());
310                            }
311    
312                            if (Validator.isNotNull(PropsValues.COMPANY_DEFAULT_TIME_ZONE)) {
313                                    defaultUser.setTimeZoneId(
314                                            PropsValues.COMPANY_DEFAULT_TIME_ZONE);
315                            }
316                            else {
317                                    TimeZone timeZone = TimeZoneUtil.getDefault();
318    
319                                    defaultUser.setTimeZoneId(timeZone.getID());
320                            }
321    
322                            defaultUser.setGreeting(
323                                    LanguageUtil.format(
324                                            defaultUser.getLocale(), "welcome-x", StringPool.BLANK,
325                                            false));
326                            defaultUser.setLoginDate(now);
327                            defaultUser.setFailedLoginAttempts(0);
328                            defaultUser.setAgreedToTermsOfUse(true);
329                            defaultUser.setStatus(WorkflowConstants.STATUS_APPROVED);
330    
331                            userPersistence.update(defaultUser);
332    
333                            // Contact
334    
335                            Contact defaultContact = contactPersistence.create(
336                                    defaultUser.getContactId());
337    
338                            defaultContact.setCompanyId(defaultUser.getCompanyId());
339                            defaultContact.setUserId(defaultUser.getUserId());
340                            defaultContact.setUserName(StringPool.BLANK);
341                            defaultContact.setCreateDate(now);
342                            defaultContact.setModifiedDate(now);
343                            defaultContact.setClassName(User.class.getName());
344                            defaultContact.setClassPK(defaultUser.getUserId());
345                            defaultContact.setAccountId(company.getAccountId());
346                            defaultContact.setParentContactId(
347                                    ContactConstants.DEFAULT_PARENT_CONTACT_ID);
348                            defaultContact.setEmailAddress(defaultUser.getEmailAddress());
349                            defaultContact.setFirstName(StringPool.BLANK);
350                            defaultContact.setMiddleName(StringPool.BLANK);
351                            defaultContact.setLastName(StringPool.BLANK);
352                            defaultContact.setMale(true);
353                            defaultContact.setBirthday(now);
354    
355                            contactPersistence.update(defaultContact);
356                    }
357    
358                    // System roles
359    
360                    roleLocalService.checkSystemRoles(companyId);
361    
362                    // System groups
363    
364                    groupLocalService.checkSystemGroups(companyId);
365    
366                    // Company group
367    
368                    groupLocalService.checkCompanyGroup(companyId);
369    
370                    // Default password policy
371    
372                    passwordPolicyLocalService.checkDefaultPasswordPolicy(companyId);
373    
374                    // Default user must have the Guest role
375    
376                    Role guestRole = roleLocalService.getRole(
377                            companyId, RoleConstants.GUEST);
378    
379                    roleLocalService.setUserRoles(
380                            defaultUser.getUserId(), new long[] {guestRole.getRoleId()});
381    
382                    // Default admin
383    
384                    if (userPersistence.countByCompanyId(companyId) == 1) {
385                            String emailAddress =
386                                    PropsValues.DEFAULT_ADMIN_EMAIL_ADDRESS_PREFIX + "@" + mx;
387    
388                            userLocalService.addDefaultAdminUser(
389                                    companyId, PropsValues.DEFAULT_ADMIN_SCREEN_NAME, emailAddress,
390                                    defaultUser.getLocale(), PropsValues.DEFAULT_ADMIN_FIRST_NAME,
391                                    PropsValues.DEFAULT_ADMIN_MIDDLE_NAME,
392                                    PropsValues.DEFAULT_ADMIN_LAST_NAME);
393                    }
394    
395                    // Portlets
396    
397                    portletLocalService.checkPortlets(companyId);
398    
399                    return company;
400            }
401    
402            /**
403             * Checks if the company has an encryption key. It will create a key if one
404             * does not exist.
405             *
406             * @param  companyId the primary key of the company
407             * @throws PortalException if a company with the primary key could not be
408             *         found
409             * @throws SystemException if a system exception occurred
410             */
411            public void checkCompanyKey(long companyId)
412                    throws PortalException, SystemException {
413    
414                    Company company = companyPersistence.findByPrimaryKey(companyId);
415    
416                    if (Validator.isNull(company.getKey()) &&
417                            (company.getKeyObj() == null)) {
418    
419                            try {
420                                    company.setKey(Base64.objectToString(Encryptor.generateKey()));
421                            }
422                            catch (EncryptorException ee) {
423                                    throw new SystemException(ee);
424                            }
425    
426                            companyPersistence.update(company);
427                    }
428            }
429    
430            /**
431             * Deletes the company's logo.
432             *
433             * @param  companyId the primary key of the company
434             * @throws PortalException if the company with the primary key could not be
435             *         found or if the company's logo could not be found
436             * @throws SystemException if a system exception occurred
437             */
438            public void deleteLogo(long companyId)
439                    throws PortalException, SystemException {
440    
441                    Company company = companyPersistence.findByPrimaryKey(companyId);
442    
443                    long logoId = company.getLogoId();
444    
445                    if (logoId > 0) {
446                            company.setLogoId(0);
447    
448                            companyPersistence.update(company);
449    
450                            imageLocalService.deleteImage(logoId);
451                    }
452            }
453    
454            /**
455             * Returns the company with the primary key.
456             *
457             * @param  companyId the primary key of the company
458             * @return the company with the primary key, <code>null</code> if a company
459             *         with the primary key could not be found
460             * @throws SystemException if a system exception occurred
461             */
462            public Company fetchCompanyById(long companyId) throws SystemException {
463                    return companyPersistence.fetchByPrimaryKey(companyId);
464            }
465    
466            /**
467             * Returns the company with the virtual host name.
468             *
469             * @param  virtualHostname the virtual host name
470             * @return the company with the virtual host name, <code>null</code> if a
471             *         company with the virtual host could not be found
472             * @throws SystemException if a system exception occurred
473             */
474            public Company fetchCompanyByVirtualHost(String virtualHostname)
475                    throws SystemException {
476    
477                    virtualHostname = virtualHostname.trim().toLowerCase();
478    
479                    VirtualHost virtualHost = virtualHostPersistence.fetchByHostname(
480                            virtualHostname);
481    
482                    if ((virtualHost == null) || (virtualHost.getLayoutSetId() != 0)) {
483                            return null;
484                    }
485    
486                    return companyPersistence.fetchByPrimaryKey(virtualHost.getCompanyId());
487            }
488    
489            /**
490             * Returns all the companies.
491             *
492             * @return the companies
493             * @throws SystemException if a system exception occurred
494             */
495            public List<Company> getCompanies() throws SystemException {
496                    return companyPersistence.findAll();
497            }
498    
499            /**
500             * Returns all the companies used by WSRP.
501             *
502             * @param  system whether the company is the very first company (i.e., the
503             *         super company)
504             * @return the companies used by WSRP
505             * @throws SystemException if a system exception occurred
506             */
507            public List<Company> getCompanies(boolean system) throws SystemException {
508                    return companyPersistence.findBySystem(system);
509            }
510    
511            /**
512             * Returns the number of companies used by WSRP.
513             *
514             * @param  system whether the company is the very first company (i.e., the
515             *         super company)
516             * @return the number of companies used by WSRP
517             * @throws SystemException if a system exception occurred
518             */
519            public int getCompaniesCount(boolean system) throws SystemException {
520                    return companyPersistence.countBySystem(system);
521            }
522    
523            /**
524             * Returns the company with the primary key.
525             *
526             * @param  companyId the primary key of the company
527             * @return the company with the primary key
528             * @throws PortalException if a company with the primary key could not be
529             *         found
530             * @throws SystemException if a system exception occurred
531             */
532            public Company getCompanyById(long companyId)
533                    throws PortalException, SystemException {
534    
535                    return companyPersistence.findByPrimaryKey(companyId);
536            }
537    
538            /**
539             * Returns the company with the logo.
540             *
541             * @param  logoId the ID of the company's logo
542             * @return the company with the logo
543             * @throws PortalException if the company with the logo could not be found
544             * @throws SystemException if a system exception occurred
545             */
546            public Company getCompanyByLogoId(long logoId)
547                    throws PortalException, SystemException {
548    
549                    return companyPersistence.findByLogoId(logoId);
550            }
551    
552            /**
553             * Returns the company with the mail domain.
554             *
555             * @param  mx the company's mail domain
556             * @return the company with the mail domain
557             * @throws PortalException if the company with the mail domain could not be
558             *         found
559             * @throws SystemException if a system exception occurred
560             */
561            public Company getCompanyByMx(String mx)
562                    throws PortalException, SystemException {
563    
564                    return companyPersistence.findByMx(mx);
565            }
566    
567            /**
568             * Returns the company with the virtual host name.
569             *
570             * @param  virtualHostname the company's virtual host name
571             * @return the company with the virtual host name
572             * @throws PortalException if the company with the virtual host name could
573             *         not be found or if the virtual host was not associated with a
574             *         company
575             * @throws SystemException if a system exception occurred
576             */
577            public Company getCompanyByVirtualHost(String virtualHostname)
578                    throws PortalException, SystemException {
579    
580                    try {
581                            virtualHostname = virtualHostname.trim().toLowerCase();
582    
583                            VirtualHost virtualHost = virtualHostPersistence.findByHostname(
584                                    virtualHostname);
585    
586                            if (virtualHost.getLayoutSetId() != 0) {
587                                    throw new CompanyVirtualHostException(
588                                            "Virtual host is associated with layout set " +
589                                                    virtualHost.getLayoutSetId());
590                            }
591    
592                            return companyPersistence.findByPrimaryKey(
593                                    virtualHost.getCompanyId());
594                    }
595                    catch (NoSuchVirtualHostException nsvhe) {
596                            throw new CompanyVirtualHostException(nsvhe);
597                    }
598            }
599    
600            /**
601             * Returns the company with the web domain.
602             *
603             * @param  webId the company's web domain
604             * @return the company with the web domain
605             * @throws PortalException if the company with the web domain could not be
606             *         found
607             * @throws SystemException if a system exception occurred
608             */
609            public Company getCompanyByWebId(String webId)
610                    throws PortalException, SystemException {
611    
612                    return companyPersistence.findByWebId(webId);
613            }
614    
615            /**
616             * Returns the user's company.
617             *
618             * @param  userId the primary key of the user
619             * @return Returns the first company if there is only one company or the
620             *         user's company if there are more than one company; <code>0</code>
621             *         otherwise
622             * @throws Exception if a user with the primary key could not be found
623             */
624            public long getCompanyIdByUserId(long userId) throws Exception {
625                    long[] companyIds = PortalInstances.getCompanyIds();
626    
627                    long companyId = 0;
628    
629                    if (companyIds.length == 1) {
630                            companyId = companyIds[0];
631                    }
632                    else if (companyIds.length > 1) {
633                            try {
634                                    User user = userPersistence.findByPrimaryKey(userId);
635    
636                                    companyId = user.getCompanyId();
637                            }
638                            catch (Exception e) {
639                                    if (_log.isWarnEnabled()) {
640                                            _log.warn(
641                                                    "Unable to get the company id for user " + userId, e);
642                                    }
643                            }
644                    }
645    
646                    return companyId;
647            }
648    
649            /**
650             * Removes the values that match the keys of the company's preferences.
651             *
652             * This method is called by {@link
653             * com.liferay.portlet.portalsettings.action.EditLDAPServerAction} remotely
654             * through {@link com.liferay.portal.service.CompanyService}.
655             *
656             * @param  companyId the primary key of the company
657             * @param  keys the company's preferences keys to be remove
658             * @throws SystemException if a system exception occurred
659             */
660            public void removePreferences(long companyId, String[] keys)
661                    throws SystemException {
662    
663                    PortletPreferences preferences = PrefsPropsUtil.getPreferences(
664                            companyId);
665    
666                    try {
667                            for (String key : keys) {
668                                    preferences.reset(key);
669                            }
670    
671                            preferences.store();
672                    }
673                    catch (Exception e) {
674                            throw new SystemException(e);
675                    }
676            }
677    
678            /**
679             * Returns an ordered range of all assets that match the keywords in the
680             * company.
681             *
682             * The method is called in {@link
683             * com.liferay.portal.search.PortalOpenSearchImpl} which is not longer used
684             * by the Search portlet.
685             *
686             * @param  companyId the primary key of the company
687             * @param  userId the primary key of the user
688             * @param  keywords the keywords (space separated),which may occur in assets
689             *         in the company (optionally <code>null</code>)
690             * @param  start the lower bound of the range of assets to return
691             * @param  end the upper bound of the range of assets to return (not
692             *         inclusive)
693             * @return the matching assets in the company
694             * @throws SystemException if a system exception occurred
695             */
696            public Hits search(
697                            long companyId, long userId, String keywords, int start, int end)
698                    throws SystemException {
699    
700                    return search(companyId, userId, null, 0, null, keywords, start, end);
701            }
702    
703            /**
704             * Returns an ordered range of all assets that match the keywords in the
705             * portlet within the company.
706             *
707             * @param  companyId the primary key of the company
708             * @param  userId the primary key of the user
709             * @param  portletId the primary key of the portlet (optionally
710             *         <code>null</code>)
711             * @param  groupId the primary key of the group (optionally <code>0</code>)
712             * @param  type the mime type of assets to return(optionally
713             *         <code>null</code>)
714             * @param  keywords the keywords (space separated), which may occur in any
715             *         assets in the portlet (optionally <code>null</code>)
716             * @param  start the lower bound of the range of assets to return
717             * @param  end the upper bound of the range of assets to return (not
718             *         inclusive)
719             * @return the matching assets in the portlet within the company
720             * @throws SystemException if a system exception occurred
721             */
722            public Hits search(
723                            long companyId, long userId, String portletId, long groupId,
724                            String type, String keywords, int start, int end)
725                    throws SystemException {
726    
727                    try {
728    
729                            // Search context
730    
731                            SearchContext searchContext = new SearchContext();
732    
733                            searchContext.setCompanyId(companyId);
734                            searchContext.setEnd(end);
735                            searchContext.setEntryClassNames(
736                                    SearchEngineUtil.getEntryClassNames());
737    
738                            if (groupId > 0) {
739                                    searchContext.setGroupIds(new long[] {groupId});
740                            }
741    
742                            searchContext.setKeywords(keywords);
743    
744                            if (Validator.isNotNull(portletId)) {
745                                    searchContext.setPortletIds(new String[] {portletId});
746                            }
747    
748                            searchContext.setStart(start);
749                            searchContext.setUserId(userId);
750    
751                            // Always add facets as late as possible so that the search context
752                            // fields can be considered by the facets
753    
754                            Facet assetEntriesFacet = new AssetEntriesFacet(searchContext);
755    
756                            assetEntriesFacet.setStatic(true);
757    
758                            searchContext.addFacet(assetEntriesFacet);
759    
760                            Facet scopeFacet = new ScopeFacet(searchContext);
761    
762                            scopeFacet.setStatic(true);
763    
764                            searchContext.addFacet(scopeFacet);
765    
766                            // Search
767    
768                            Indexer indexer = FacetedSearcher.getInstance();
769    
770                            return indexer.search(searchContext);
771                    }
772                    catch (Exception e) {
773                            throw new SystemException(e);
774                    }
775            }
776    
777            /**
778             * Updates the company.
779             *
780             * @param  companyId the primary key of the company
781             * @param  virtualHostname the company's virtual host name
782             * @param  mx the company's mail domain
783             * @param  maxUsers the max number of company users (optionally
784             *         <code>0</code>)
785             * @param  active whether the company is active
786             * @return the company with the primary key
787             * @throws PortalException if a company with primary key could not be found
788             *         or if the new information was invalid
789             * @throws SystemException if a system exception occurred
790             */
791            public Company updateCompany(
792                            long companyId, String virtualHostname, String mx, int maxUsers,
793                            boolean active)
794                    throws PortalException, SystemException {
795    
796                    // Company
797    
798                    virtualHostname = virtualHostname.trim().toLowerCase();
799    
800                    if (!active) {
801                            if (companyId == PortalInstances.getDefaultCompanyId()) {
802                                    active = true;
803                            }
804                    }
805    
806                    Company company = companyPersistence.findByPrimaryKey(companyId);
807    
808                    validate(company.getWebId(), virtualHostname, mx);
809    
810                    if (PropsValues.MAIL_MX_UPDATE) {
811                            company.setMx(mx);
812                    }
813    
814                    company.setMaxUsers(maxUsers);
815                    company.setActive(active);
816    
817                    companyPersistence.update(company);
818    
819                    // Virtual host
820    
821                    updateVirtualHost(companyId, virtualHostname);
822    
823                    return company;
824            }
825    
826            /**
827             * Update the company with additional account information.
828             *
829             * @param  companyId the primary key of the company
830             * @param  virtualHostname the company's virtual host name
831             * @param  mx the company's mail domain
832             * @param  homeURL the company's home URL (optionally <code>null</code>)
833             * @param  name the company's account name(optionally <code>null</code>)
834             * @param  legalName the company's account legal name (optionally
835             *         <code>null</code>)
836             * @param  legalId the company's account legal ID (optionally
837             *         <code>null</code>)
838             * @param  legalType the company's account legal type (optionally
839             *         <code>null</code>)
840             * @param  sicCode the company's account SIC code (optionally
841             *         <code>null</code>)
842             * @param  tickerSymbol the company's account ticker symbol (optionally
843             *         <code>null</code>)
844             * @param  industry the company's account industry (optionally
845             *         <code>null</code>)
846             * @param  type the company's account type (optionally <code>null</code>)
847             * @param  size the company's account size (optionally <code>null</code>)
848             * @return the company with the primary key
849             * @throws PortalException if a company with the primary key could not be
850             *         found or if the new information was invalid
851             * @throws SystemException if a system exception occurred
852             */
853            public Company updateCompany(
854                            long companyId, String virtualHostname, String mx, String homeURL,
855                            String name, String legalName, String legalId, String legalType,
856                            String sicCode, String tickerSymbol, String industry, String type,
857                            String size)
858                    throws PortalException, SystemException {
859    
860                    // Company
861    
862                    virtualHostname = virtualHostname.trim().toLowerCase();
863    
864                    Company company = companyPersistence.findByPrimaryKey(companyId);
865    
866                    validate(company.getWebId(), virtualHostname, mx);
867                    validate(companyId, name);
868    
869                    if (PropsValues.MAIL_MX_UPDATE) {
870                            company.setMx(mx);
871                    }
872    
873                    company.setHomeURL(homeURL);
874    
875                    companyPersistence.update(company);
876    
877                    // Account
878    
879                    updateAccount(
880                            company, name, legalName, legalId, legalType, sicCode, tickerSymbol,
881                            industry, type, size);
882    
883                    // Virtual host
884    
885                    updateVirtualHost(companyId, virtualHostname);
886    
887                    return company;
888            }
889    
890            /**
891             * Update the company's display.
892             *
893             * @param  companyId the primary key of the company
894             * @param  languageId the ID of the company's default user's language
895             * @param  timeZoneId the ID of the company's default user's time zone
896             * @throws PortalException if the company's default user could not be found
897             * @throws SystemException if a system exception occurred
898             */
899            public void updateDisplay(
900                            long companyId, String languageId, String timeZoneId)
901                    throws PortalException, SystemException {
902    
903                    User user = userLocalService.getDefaultUser(companyId);
904    
905                    user.setLanguageId(languageId);
906                    user.setTimeZoneId(timeZoneId);
907    
908                    userPersistence.update(user);
909            }
910    
911            /**
912             * Updates the company's logo.
913             *
914             * @param  companyId the primary key of the company
915             * @param  bytes the bytes of the company's logo image
916             * @return the company with the primary key
917             * @throws PortalException if the company's logo ID could not be found or if
918             *         the logo's image was corrupted
919             * @throws SystemException if a system exception occurred
920             */
921            public Company updateLogo(long companyId, byte[] bytes)
922                    throws PortalException, SystemException {
923    
924                    Company company = checkLogo(companyId);
925    
926                    imageLocalService.updateImage(company.getLogoId(), bytes);
927    
928                    return company;
929            }
930    
931            /**
932             * Updates the company's logo.
933             *
934             * @param  companyId the primary key of the company
935             * @param  file the file of the company's logo image
936             * @return the company with the primary key
937             * @throws PortalException the company's logo ID could not be found or if
938             *         the logo's image was corrupted
939             * @throws SystemException if a system exception occurred
940             */
941            public Company updateLogo(long companyId, File file)
942                    throws PortalException, SystemException {
943    
944                    Company company = checkLogo(companyId);
945    
946                    imageLocalService.updateImage(company.getLogoId(), file);
947    
948                    return company;
949            }
950    
951            /**
952             * Update the company's logo.
953             *
954             * @param  companyId the primary key of the company
955             * @param  is the input stream of the company's logo image
956             * @return the company with the primary key
957             * @throws PortalException if the company's logo ID could not be found or if
958             *         the company's logo image was corrupted
959             * @throws SystemException if a system exception occurred
960             */
961            public Company updateLogo(long companyId, InputStream is)
962                    throws PortalException, SystemException {
963    
964                    Company company = checkLogo(companyId);
965    
966                    imageLocalService.updateImage(company.getLogoId(), is);
967    
968                    return company;
969            }
970    
971            /**
972             * Updates the company's preferences. The company's default properties are
973             * found in portal.properties.
974             *
975             * @param  companyId the primary key of the company
976             * @param  properties the company's properties. See {@link
977             *         com.liferay.portal.kernel.util.UnicodeProperties}
978             * @throws PortalException if the properties contained new locales that were
979             *         not supported
980             * @throws SystemException if a system exception occurred
981             */
982            public void updatePreferences(long companyId, UnicodeProperties properties)
983                    throws PortalException, SystemException {
984    
985                    PortletPreferences preferences = PrefsPropsUtil.getPreferences(
986                            companyId);
987    
988                    try {
989                            String newLocales = properties.getProperty(PropsKeys.LOCALES);
990    
991                            if (newLocales != null) {
992                                    String oldLocales = preferences.getValue(
993                                            PropsKeys.LOCALES, StringPool.BLANK);
994    
995                                    if (!Validator.equals(oldLocales, newLocales)) {
996                                            validateLocales(newLocales);
997    
998                                            LanguageUtil.resetAvailableLocales(companyId);
999                                    }
1000                            }
1001    
1002                            List<String> resetKeys = new ArrayList<String>();
1003    
1004                            for (Map.Entry<String, String> entry : properties.entrySet()) {
1005                                    String key = entry.getKey();
1006                                    String value = entry.getValue();
1007    
1008                                    if (value.equals(Portal.TEMP_OBFUSCATION_VALUE)) {
1009                                            continue;
1010                                    }
1011    
1012                                    String propsUtilValue = PropsUtil.get(key);
1013    
1014                                    if (!value.equals(propsUtilValue)) {
1015                                            preferences.setValue(key, value);
1016                                    }
1017                                    else {
1018                                            String preferencesValue = preferences.getValue(key, null);
1019    
1020                                            if (preferencesValue != null) {
1021                                                    resetKeys.add(key);
1022                                            }
1023                                    }
1024                            }
1025    
1026                            for (String key : resetKeys) {
1027                                    preferences.reset(key);
1028                            }
1029    
1030                            preferences.store();
1031                    }
1032                    catch (LocaleException le) {
1033                            throw le;
1034                    }
1035                    catch (Exception e) {
1036                            throw new SystemException(e);
1037                    }
1038            }
1039    
1040            /**
1041             * Updates the company's security properties.
1042             *
1043             * @param  companyId the primary key of the company
1044             * @param  authType the company's method of authenticating users
1045             * @param  autoLogin whether to allow users to select the "remember me"
1046             *         feature
1047             * @param  sendPassword whether to allow users to ask the company to send
1048             *         their password
1049             * @param  strangers whether to allow strangers to create accounts register
1050             *         themselves in the company
1051             * @param  strangersWithMx whether to allow strangers to create accounts
1052             *         with email addresses that match the company mail suffix
1053             * @param  strangersVerify whether to require strangers who create accounts
1054             *         to be verified via email
1055             * @param  siteLogo whether to allow site administrators to use their own
1056             *         logo instead of the enterprise logo
1057             * @throws SystemException if a system exception occurred
1058             */
1059            public void updateSecurity(
1060                            long companyId, String authType, boolean autoLogin,
1061                            boolean sendPassword, boolean strangers, boolean strangersWithMx,
1062                            boolean strangersVerify, boolean siteLogo)
1063                    throws SystemException {
1064    
1065                    PortletPreferences preferences = PrefsPropsUtil.getPreferences(
1066                            companyId);
1067    
1068                    try {
1069                            preferences.setValue(
1070                                    PropsKeys.COMPANY_SECURITY_AUTH_TYPE, authType);
1071                            preferences.setValue(
1072                                    PropsKeys.COMPANY_SECURITY_AUTO_LOGIN,
1073                                    String.valueOf(autoLogin));
1074                            preferences.setValue(
1075                                    PropsKeys.COMPANY_SECURITY_SEND_PASSWORD,
1076                                    String.valueOf(sendPassword));
1077                            preferences.setValue(
1078                                    PropsKeys.COMPANY_SECURITY_STRANGERS,
1079                                    String.valueOf(strangers));
1080                            preferences.setValue(
1081                                    PropsKeys.COMPANY_SECURITY_STRANGERS_WITH_MX,
1082                                    String.valueOf(strangersWithMx));
1083                            preferences.setValue(
1084                                    PropsKeys.COMPANY_SECURITY_STRANGERS_VERIFY,
1085                                    String.valueOf(strangersVerify));
1086                            preferences.setValue(
1087                                    PropsKeys.COMPANY_SECURITY_SITE_LOGO, String.valueOf(siteLogo));
1088    
1089                            preferences.store();
1090                    }
1091                    catch (IOException ioe) {
1092                            throw new SystemException(ioe);
1093                    }
1094                    catch (PortletException pe) {
1095                            throw new SystemException(pe);
1096                    }
1097            }
1098    
1099            protected Company checkLogo(long companyId)
1100                    throws PortalException, SystemException {
1101    
1102                    Company company = companyPersistence.findByPrimaryKey(companyId);
1103    
1104                    long logoId = company.getLogoId();
1105    
1106                    if (logoId <= 0) {
1107                            logoId = counterLocalService.increment();
1108    
1109                            company.setLogoId(logoId);
1110    
1111                            company = companyPersistence.update(company);
1112                    }
1113    
1114                    return company;
1115            }
1116    
1117            protected void updateAccount(
1118                            Company company, String name, String legalName, String legalId,
1119                            String legalType, String sicCode, String tickerSymbol,
1120                            String industry, String type, String size)
1121                    throws SystemException {
1122    
1123                    Date now = new Date();
1124    
1125                    Account account = accountPersistence.fetchByPrimaryKey(
1126                            company.getAccountId());
1127    
1128                    if (account == null) {
1129                            long accountId = counterLocalService.increment();
1130    
1131                            account = accountPersistence.create(accountId);
1132    
1133                            account.setCompanyId(company.getCompanyId());
1134                            account.setCreateDate(now);
1135                            account.setUserId(0);
1136                            account.setUserName(StringPool.BLANK);
1137    
1138                            company.setAccountId(accountId);
1139    
1140                            companyPersistence.update(company);
1141                    }
1142    
1143                    account.setModifiedDate(now);
1144                    account.setName(name);
1145                    account.setLegalName(legalName);
1146                    account.setLegalId(legalId);
1147                    account.setLegalType(legalType);
1148                    account.setSicCode(sicCode);
1149                    account.setTickerSymbol(tickerSymbol);
1150                    account.setIndustry(industry);
1151                    account.setType(type);
1152                    account.setSize(size);
1153    
1154                    accountPersistence.update(account);
1155            }
1156    
1157            protected void updateVirtualHost(long companyId, String virtualHostname)
1158                    throws CompanyVirtualHostException, SystemException {
1159    
1160                    if (Validator.isNotNull(virtualHostname)) {
1161                            try {
1162                                    VirtualHost virtualHost = virtualHostPersistence.findByHostname(
1163                                            virtualHostname);
1164    
1165                                    if ((virtualHost.getCompanyId() != companyId) ||
1166                                            (virtualHost.getLayoutSetId() != 0)) {
1167    
1168                                            throw new CompanyVirtualHostException();
1169                                    }
1170                            }
1171                            catch (NoSuchVirtualHostException nsvhe) {
1172                                    virtualHostLocalService.updateVirtualHost(
1173                                            companyId, 0, virtualHostname);
1174                            }
1175                    }
1176                    else {
1177                            try {
1178                                    virtualHostPersistence.removeByC_L(companyId, 0);
1179                            }
1180                            catch (NoSuchVirtualHostException nsvhe) {
1181                            }
1182                    }
1183            }
1184    
1185            protected void validate(long companyId, String name)
1186                    throws PortalException, SystemException {
1187    
1188                    Group group = groupLocalService.fetchGroup(companyId, name);
1189    
1190                    if ((group != null) || Validator.isNull(name)) {
1191                            throw new AccountNameException();
1192                    }
1193            }
1194    
1195            protected void validate(String webId, String virtualHostname, String mx)
1196                    throws PortalException, SystemException {
1197    
1198                    if (Validator.isNull(virtualHostname)) {
1199                            throw new CompanyVirtualHostException();
1200                    }
1201                    else if (virtualHostname.equals(_DEFAULT_VIRTUAL_HOST) &&
1202                                     !webId.equals(PropsValues.COMPANY_DEFAULT_WEB_ID)) {
1203    
1204                            throw new CompanyVirtualHostException();
1205                    }
1206                    else if (!Validator.isDomain(virtualHostname)) {
1207                            throw new CompanyVirtualHostException();
1208                    }
1209                    else {
1210                            try {
1211                                    VirtualHost virtualHost = virtualHostPersistence.findByHostname(
1212                                            virtualHostname);
1213    
1214                                    long companyId = virtualHost.getCompanyId();
1215    
1216                                    Company virtualHostnameCompany =
1217                                            companyPersistence.findByPrimaryKey(companyId);
1218    
1219                                    if (!virtualHostnameCompany.getWebId().equals(webId)) {
1220                                            throw new CompanyVirtualHostException();
1221                                    }
1222                            }
1223                            catch (NoSuchVirtualHostException nsvhe) {
1224                            }
1225                    }
1226    
1227                    if (Validator.isNull(mx)) {
1228                            throw new CompanyMxException();
1229                    }
1230                    else if (!Validator.isDomain(mx)) {
1231                            throw new CompanyMxException();
1232                    }
1233            }
1234    
1235            protected void validateLocales(String locales) throws PortalException {
1236                    String[] localesArray = StringUtil.split(locales, StringPool.COMMA);
1237    
1238                    for (String locale : localesArray) {
1239                            if (!ArrayUtil.contains(PropsValues.LOCALES, locale)) {
1240                                    throw new LocaleException();
1241                            }
1242                    }
1243            }
1244    
1245            private static final String _DEFAULT_VIRTUAL_HOST = "localhost";
1246    
1247            private static Log _log = LogFactoryUtil.getLog(
1248                    CompanyLocalServiceImpl.class);
1249    
1250    }