001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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, false);
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, false);
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, false);
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, false);
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.setAccountId(company.getAccountId());
344                            defaultContact.setParentContactId(
345                                    ContactConstants.DEFAULT_PARENT_CONTACT_ID);
346                            defaultContact.setFirstName(StringPool.BLANK);
347                            defaultContact.setMiddleName(StringPool.BLANK);
348                            defaultContact.setLastName(StringPool.BLANK);
349                            defaultContact.setMale(true);
350                            defaultContact.setBirthday(now);
351    
352                            contactPersistence.update(defaultContact, false);
353                    }
354    
355                    // System roles
356    
357                    roleLocalService.checkSystemRoles(companyId);
358    
359                    // System groups
360    
361                    groupLocalService.checkSystemGroups(companyId);
362    
363                    // Company group
364    
365                    groupLocalService.checkCompanyGroup(companyId);
366    
367                    // Default password policy
368    
369                    passwordPolicyLocalService.checkDefaultPasswordPolicy(companyId);
370    
371                    // Default user must have the Guest role
372    
373                    Role guestRole = roleLocalService.getRole(
374                            companyId, RoleConstants.GUEST);
375    
376                    roleLocalService.setUserRoles(
377                            defaultUser.getUserId(), new long[] {guestRole.getRoleId()});
378    
379                    // Default admin
380    
381                    if (userPersistence.countByCompanyId(companyId) == 1) {
382                            String emailAddress =
383                                    PropsValues.DEFAULT_ADMIN_EMAIL_ADDRESS_PREFIX + "@" + mx;
384    
385                            userLocalService.addDefaultAdminUser(
386                                    companyId, PropsValues.DEFAULT_ADMIN_SCREEN_NAME, emailAddress,
387                                    defaultUser.getLocale(), PropsValues.DEFAULT_ADMIN_FIRST_NAME,
388                                    PropsValues.DEFAULT_ADMIN_MIDDLE_NAME,
389                                    PropsValues.DEFAULT_ADMIN_LAST_NAME);
390                    }
391    
392                    // Portlets
393    
394                    portletLocalService.checkPortlets(companyId);
395    
396                    return company;
397            }
398    
399            /**
400             * Checks if the company has an encryption key. It will create a key if one
401             * does not exist.
402             *
403             * @param  companyId the primary key of the company
404             * @throws PortalException if a company with the primary key could not be
405             *         found
406             * @throws SystemException if a system exception occurred
407             */
408            public void checkCompanyKey(long companyId)
409                    throws PortalException, SystemException {
410    
411                    Company company = companyPersistence.findByPrimaryKey(companyId);
412    
413                    if (Validator.isNull(company.getKey()) &&
414                            (company.getKeyObj() == null)) {
415    
416                            try {
417                                    company.setKey(Base64.objectToString(Encryptor.generateKey()));
418                            }
419                            catch (EncryptorException ee) {
420                                    throw new SystemException(ee);
421                            }
422    
423                            companyPersistence.update(company, false);
424                    }
425            }
426    
427            /**
428             * Deletes the company's logo.
429             *
430             * @param  companyId the primary key of the company
431             * @throws PortalException if the company with the primary key could not be
432             *         found or if the company's logo could not be found
433             * @throws SystemException if a system exception occurred
434             */
435            public void deleteLogo(long companyId)
436                    throws PortalException, SystemException {
437    
438                    Company company = companyPersistence.findByPrimaryKey(companyId);
439    
440                    long logoId = company.getLogoId();
441    
442                    if (logoId > 0) {
443                            company.setLogoId(0);
444    
445                            companyPersistence.update(company, false);
446    
447                            imageLocalService.deleteImage(logoId);
448                    }
449            }
450    
451            /**
452             * Returns the company with the primary key.
453             *
454             * @param  companyId the primary key of the company
455             * @return the company with the primary key, <code>null</code> if a company
456             *         with the primary key could not be found
457             * @throws SystemException if a system exception occurred
458             */
459            public Company fetchCompanyById(long companyId) throws SystemException {
460                    return companyPersistence.fetchByPrimaryKey(companyId);
461            }
462    
463            /**
464             * Returns the company with the virtual host name.
465             *
466             * @param  virtualHostname the virtual host name
467             * @return the company with the virtual host name, <code>null</code> if a
468             *         company with the virtual host could not be found
469             * @throws SystemException if a system exception occurred
470             */
471            public Company fetchCompanyByVirtualHost(String virtualHostname)
472                    throws SystemException {
473    
474                    virtualHostname = virtualHostname.trim().toLowerCase();
475    
476                    VirtualHost virtualHost = virtualHostPersistence.fetchByHostname(
477                            virtualHostname);
478    
479                    if ((virtualHost == null) || (virtualHost.getLayoutSetId() != 0)) {
480                            return null;
481                    }
482    
483                    return companyPersistence.fetchByPrimaryKey(virtualHost.getCompanyId());
484            }
485    
486            /**
487             * Returns all the companies.
488             *
489             * @return the companies
490             * @throws SystemException if a system exception occurred
491             */
492            public List<Company> getCompanies() throws SystemException {
493                    return companyPersistence.findAll();
494            }
495    
496            /**
497             * Returns all the companies used by WSRP.
498             *
499             * @param  system whether the company is the very first company (i.e., the
500             *         super company)
501             * @return the companies used by WSRP
502             * @throws SystemException if a system exception occurred
503             */
504            public List<Company> getCompanies(boolean system) throws SystemException {
505                    return companyPersistence.findBySystem(system);
506            }
507    
508            /**
509             * Returns the number of companies used by WSRP.
510             *
511             * @param  system whether the company is the very first company (i.e., the
512             *         super company)
513             * @return the number of companies used by WSRP
514             * @throws SystemException if a system exception occurred
515             */
516            public int getCompaniesCount(boolean system) throws SystemException {
517                    return companyPersistence.countBySystem(system);
518            }
519    
520            /**
521             * Returns the company with the primary key.
522             *
523             * @param  companyId the primary key of the company
524             * @return the company with the primary key
525             * @throws PortalException if a company with the primary key could not be
526             *         found
527             * @throws SystemException if a system exception occurred
528             */
529            public Company getCompanyById(long companyId)
530                    throws PortalException, SystemException {
531    
532                    return companyPersistence.findByPrimaryKey(companyId);
533            }
534    
535            /**
536             * Returns the company with the logo.
537             *
538             * @param  logoId the ID of the company's logo
539             * @return the company with the logo
540             * @throws PortalException if the company with the logo could not be found
541             * @throws SystemException if a system exception occurred
542             */
543            public Company getCompanyByLogoId(long logoId)
544                    throws PortalException, SystemException {
545    
546                    return companyPersistence.findByLogoId(logoId);
547            }
548    
549            /**
550             * Returns the company with the mail domain.
551             *
552             * @param  mx the company's mail domain
553             * @return the company with the mail domain
554             * @throws PortalException if the company with the mail domain could not be
555             *         found
556             * @throws SystemException if a system exception occurred
557             */
558            public Company getCompanyByMx(String mx)
559                    throws PortalException, SystemException {
560    
561                    return companyPersistence.findByMx(mx);
562            }
563    
564            /**
565             * Returns the company with the virtual host name.
566             *
567             * @param  virtualHostname the company's virtual host name
568             * @return the company with the virtual host name
569             * @throws PortalException if the company with the virtual host name could
570             *         not be found or if the virtual host was not associated with a
571             *         company
572             * @throws SystemException if a system exception occurred
573             */
574            public Company getCompanyByVirtualHost(String virtualHostname)
575                    throws PortalException, SystemException {
576    
577                    try {
578                            virtualHostname = virtualHostname.trim().toLowerCase();
579    
580                            VirtualHost virtualHost = virtualHostPersistence.findByHostname(
581                                    virtualHostname);
582    
583                            if (virtualHost.getLayoutSetId() != 0) {
584                                    throw new CompanyVirtualHostException(
585                                            "Virtual host is associated with layout set " +
586                                                    virtualHost.getLayoutSetId());
587                            }
588    
589                            return companyPersistence.findByPrimaryKey(
590                                    virtualHost.getCompanyId());
591                    }
592                    catch (NoSuchVirtualHostException nsvhe) {
593                            throw new CompanyVirtualHostException(nsvhe);
594                    }
595            }
596    
597            /**
598             * Returns the company with the web domain.
599             *
600             * @param  webId the company's web domain
601             * @return the company with the web domain
602             * @throws PortalException if the company with the web domain could not be
603             *         found
604             * @throws SystemException if a system exception occurred
605             */
606            public Company getCompanyByWebId(String webId)
607                    throws PortalException, SystemException {
608    
609                    return companyPersistence.findByWebId(webId);
610            }
611    
612            /**
613             * Returns the user's company.
614             *
615             * @param  userId the primary key of the user
616             * @return Returns the first company if there is only one company or the
617             *         user's company if there are more than one company; <code>0</code>
618             *         otherwise
619             * @throws Exception if a user with the primary key could not be found
620             */
621            public long getCompanyIdByUserId(long userId) throws Exception {
622                    long[] companyIds = PortalInstances.getCompanyIds();
623    
624                    long companyId = 0;
625    
626                    if (companyIds.length == 1) {
627                            companyId = companyIds[0];
628                    }
629                    else if (companyIds.length > 1) {
630                            try {
631                                    User user = userPersistence.findByPrimaryKey(userId);
632    
633                                    companyId = user.getCompanyId();
634                            }
635                            catch (Exception e) {
636                                    if (_log.isWarnEnabled()) {
637                                            _log.warn(
638                                                    "Unable to get the company id for user " + userId, e);
639                                    }
640                            }
641                    }
642    
643                    return companyId;
644            }
645    
646            /**
647             * Removes the values that match the keys of the company's preferences.
648             *
649             * This method is called by {@link
650             * com.liferay.portlet.portalsettings.action.EditLDAPServerAction} remotely
651             * through {@link com.liferay.portal.service.CompanyService}.
652             *
653             * @param  companyId the primary key of the company
654             * @param  keys the company's preferences keys to be remove
655             * @throws SystemException if a system exception occurred
656             */
657            public void removePreferences(long companyId, String[] keys)
658                    throws SystemException {
659    
660                    PortletPreferences preferences = PrefsPropsUtil.getPreferences(
661                            companyId);
662    
663                    try {
664                            for (String key : keys) {
665                                    preferences.reset(key);
666                            }
667    
668                            preferences.store();
669                    }
670                    catch (Exception e) {
671                            throw new SystemException(e);
672                    }
673            }
674    
675            /**
676             * Returns an ordered range of all assets that match the keywords in the
677             * company.
678             *
679             * The method is called in {@link
680             * com.liferay.portal.search.PortalOpenSearchImpl} which is not longer used
681             * by the Search portlet.
682             *
683             * @param  companyId the primary key of the company
684             * @param  userId the primary key of the user
685             * @param  keywords the keywords (space separated),which may occur in assets
686             *         in the company (optionally <code>null</code>)
687             * @param  start the lower bound of the range of assets to return
688             * @param  end the upper bound of the range of assets to return (not
689             *         inclusive)
690             * @return the matching assets in the company
691             * @throws SystemException if a system exception occurred
692             */
693            public Hits search(
694                            long companyId, long userId, String keywords, int start, int end)
695                    throws SystemException {
696    
697                    return search(companyId, userId, null, 0, null, keywords, start, end);
698            }
699    
700            /**
701             * Returns an ordered range of all assets that match the keywords in the
702             * portlet within the company.
703             *
704             * @param  companyId the primary key of the company
705             * @param  userId the primary key of the user
706             * @param  portletId the primary key of the portlet (optionally
707             *         <code>null</code>)
708             * @param  groupId the primary key of the group (optionally <code>0</code>)
709             * @param  type the mime type of assets to return(optionally
710             *         <code>null</code>)
711             * @param  keywords the keywords (space separated), which may occur in any
712             *         assets in the portlet (optionally <code>null</code>)
713             * @param  start the lower bound of the range of assets to return
714             * @param  end the upper bound of the range of assets to return (not
715             *         inclusive)
716             * @return the matching assets in the portlet within the company
717             * @throws SystemException if a system exception occurred
718             */
719            public Hits search(
720                            long companyId, long userId, String portletId, long groupId,
721                            String type, String keywords, int start, int end)
722                    throws SystemException {
723    
724                    try {
725    
726                            // Search context
727    
728                            SearchContext searchContext = new SearchContext();
729    
730                            searchContext.setCompanyId(companyId);
731                            searchContext.setEnd(end);
732                            searchContext.setEntryClassNames(
733                                    SearchEngineUtil.getEntryClassNames());
734    
735                            if (groupId > 0) {
736                                    searchContext.setGroupIds(new long[]{groupId});
737                            }
738    
739                            searchContext.setKeywords(keywords);
740    
741                            if (Validator.isNotNull(portletId)) {
742                                    searchContext.setPortletIds(new String[] {portletId});
743                            }
744    
745                            searchContext.setStart(start);
746                            searchContext.setUserId(userId);
747    
748                            // Always add facets as late as possible so that the search context
749                            // fields can be considered by the facets
750    
751                            Facet assetEntriesFacet = new AssetEntriesFacet(searchContext);
752    
753                            assetEntriesFacet.setStatic(true);
754    
755                            searchContext.addFacet(assetEntriesFacet);
756    
757                            Facet scopeFacet = new ScopeFacet(searchContext);
758    
759                            scopeFacet.setStatic(true);
760    
761                            searchContext.addFacet(scopeFacet);
762    
763                            // Search
764    
765                            Indexer indexer = FacetedSearcher.getInstance();
766    
767                            return indexer.search(searchContext);
768                    }
769                    catch (Exception e) {
770                            throw new SystemException(e);
771                    }
772            }
773    
774            /**
775             * Updates the company.
776             *
777             * @param  companyId the primary key of the company
778             * @param  virtualHostname the company's virtual host name
779             * @param  mx the company's mail domain
780             * @param  maxUsers the max number of company users (optionally
781             *         <code>0</code>)
782             * @param  active whether the company is active
783             * @return the company with the primary key
784             * @throws PortalException if a company with primary key could not be found
785             *         or if the new information was invalid
786             * @throws SystemException if a system exception occurred
787             */
788            public Company updateCompany(
789                            long companyId, String virtualHostname, String mx, int maxUsers,
790                            boolean active)
791                    throws PortalException, SystemException {
792    
793                    // Company
794    
795                    virtualHostname = virtualHostname.trim().toLowerCase();
796    
797                    if (!active) {
798                            if (companyId == PortalInstances.getDefaultCompanyId()) {
799                                    active = true;
800                            }
801                    }
802    
803                    Company company = companyPersistence.findByPrimaryKey(companyId);
804    
805                    validate(company.getWebId(), virtualHostname, mx);
806    
807                    if (PropsValues.MAIL_MX_UPDATE) {
808                            company.setMx(mx);
809                    }
810    
811                    company.setMaxUsers(maxUsers);
812                    company.setActive(active);
813    
814                    companyPersistence.update(company, false);
815    
816                    // Virtual host
817    
818                    updateVirtualHost(companyId, virtualHostname);
819    
820                    return company;
821            }
822    
823            /**
824             * Update the company with additional account information.
825             *
826             * @param  companyId the primary key of the company
827             * @param  virtualHostname the company's virtual host name
828             * @param  mx the company's mail domain
829             * @param  homeURL the company's home URL (optionally <code>null</code>)
830             * @param  name the company's account name(optionally <code>null</code>)
831             * @param  legalName the company's account legal name (optionally
832             *         <code>null</code>)
833             * @param  legalId the company's account legal ID (optionally
834             *         <code>null</code>)
835             * @param  legalType the company's account legal type (optionally
836             *         <code>null</code>)
837             * @param  sicCode the company's account SIC code (optionally
838             *         <code>null</code>)
839             * @param  tickerSymbol the company's account ticker symbol (optionally
840             *         <code>null</code>)
841             * @param  industry the company's account industry (optionally
842             *         <code>null</code>)
843             * @param  type the company's account type (optionally <code>null</code>)
844             * @param  size the company's account size (optionally <code>null</code>)
845             * @return the company with the primary key
846             * @throws PortalException if a company with the primary key could not be
847             *         found or if the new information was invalid
848             * @throws SystemException if a system exception occurred
849             */
850            public Company updateCompany(
851                            long companyId, String virtualHostname, String mx, String homeURL,
852                            String name, String legalName, String legalId, String legalType,
853                            String sicCode, String tickerSymbol, String industry, String type,
854                            String size)
855                    throws PortalException, SystemException {
856    
857                    // Company
858    
859                    virtualHostname = virtualHostname.trim().toLowerCase();
860    
861                    Company company = companyPersistence.findByPrimaryKey(companyId);
862    
863                    validate(company.getWebId(), virtualHostname, mx);
864                    validate(companyId, name);
865    
866                    if (PropsValues.MAIL_MX_UPDATE) {
867                            company.setMx(mx);
868                    }
869    
870                    company.setHomeURL(homeURL);
871    
872                    companyPersistence.update(company, false);
873    
874                    // Account
875    
876                    updateAccount(
877                            company, name, legalName, legalId, legalType, sicCode, tickerSymbol,
878                            industry, type, size);
879    
880                    // Virtual host
881    
882                    updateVirtualHost(companyId, virtualHostname);
883    
884                    return company;
885            }
886    
887            /**
888             * Update the company's display.
889             *
890             * @param  companyId the primary key of the company
891             * @param  languageId the ID of the company's default user's language
892             * @param  timeZoneId the ID of the company's default user's time zone
893             * @throws PortalException if the company's default user could not be found
894             * @throws SystemException if a system exception occurred
895             */
896            public void updateDisplay(
897                            long companyId, String languageId, String timeZoneId)
898                    throws PortalException, SystemException {
899    
900                    User user = userLocalService.getDefaultUser(companyId);
901    
902                    user.setLanguageId(languageId);
903                    user.setTimeZoneId(timeZoneId);
904    
905                    userPersistence.update(user, false);
906            }
907    
908            /**
909             * Updates the company's logo.
910             *
911             * @param  companyId the primary key of the company
912             * @param  bytes the bytes of the company's logo image
913             * @return the company with the primary key
914             * @throws PortalException if the company's logo ID could not be found or if
915             *         the logo's image was corrupted
916             * @throws SystemException if a system exception occurred
917             */
918            public Company updateLogo(long companyId, byte[] bytes)
919                    throws PortalException, SystemException {
920    
921                    Company company = checkLogo(companyId);
922    
923                    imageLocalService.updateImage(company.getLogoId(), bytes);
924    
925                    return company;
926            }
927    
928            /**
929             * Updates the company's logo.
930             *
931             * @param  companyId the primary key of the company
932             * @param  file the file of the company's logo image
933             * @return the company with the primary key
934             * @throws PortalException the company's logo ID could not be found or if
935             *         the logo's image was corrupted
936             * @throws SystemException if a system exception occurred
937             */
938            public Company updateLogo(long companyId, File file)
939                    throws PortalException, SystemException {
940    
941                    Company company = checkLogo(companyId);
942    
943                    imageLocalService.updateImage(company.getLogoId(), file);
944    
945                    return company;
946            }
947    
948            /**
949             * Update the company's logo.
950             *
951             * @param  companyId the primary key of the company
952             * @param  is the input stream of the company's logo image
953             * @return the company with the primary key
954             * @throws PortalException if the company's logo ID could not be found or if
955             *         the company's logo image was corrupted
956             * @throws SystemException if a system exception occurred
957             */
958            public Company updateLogo(long companyId, InputStream is)
959                    throws PortalException, SystemException {
960    
961                    Company company = checkLogo(companyId);
962    
963                    imageLocalService.updateImage(company.getLogoId(), is);
964    
965                    return company;
966            }
967    
968            /**
969             * Updates the company's preferences. The company's default properties are
970             * found in portal.properties.
971             *
972             * @param  companyId the primary key of the company
973             * @param  properties the company's properties. See {@link
974             *         com.liferay.portal.kernel.util.UnicodeProperties}
975             * @throws PortalException if the properties contained new locales that were
976             *         not supported
977             * @throws SystemException if a system exception occurred
978             */
979            public void updatePreferences(long companyId, UnicodeProperties properties)
980                    throws PortalException, SystemException {
981    
982                    PortletPreferences preferences = PrefsPropsUtil.getPreferences(
983                            companyId);
984    
985                    try {
986                            String newLocales = properties.getProperty(PropsKeys.LOCALES);
987    
988                            if (newLocales != null) {
989                                    String oldLocales = preferences.getValue(
990                                            PropsKeys.LOCALES, StringPool.BLANK);
991    
992                                    if (!Validator.equals(oldLocales, newLocales)) {
993                                            validateLocales(newLocales);
994    
995                                            LanguageUtil.resetAvailableLocales(companyId);
996                                    }
997                            }
998    
999                            List<String> resetKeys = new ArrayList<String>();
1000    
1001                            for (Map.Entry<String, String> entry : properties.entrySet()) {
1002                                    String key = entry.getKey();
1003                                    String value = entry.getValue();
1004    
1005                                    if (value.equals(Portal.TEMP_OBFUSCATION_VALUE)) {
1006                                            continue;
1007                                    }
1008    
1009                                    String propsUtilValue = PropsUtil.get(key);
1010    
1011                                    if (!value.equals(propsUtilValue)) {
1012                                            preferences.setValue(key, value);
1013                                    }
1014                                    else {
1015                                            String preferencesValue = preferences.getValue(key, null);
1016    
1017                                            if (preferencesValue != null) {
1018                                                    resetKeys.add(key);
1019                                            }
1020                                    }
1021                            }
1022    
1023                            for (String key : resetKeys) {
1024                                    preferences.reset(key);
1025                            }
1026    
1027                            preferences.store();
1028                    }
1029                    catch (LocaleException le) {
1030                            throw le;
1031                    }
1032                    catch (Exception e) {
1033                            throw new SystemException(e);
1034                    }
1035            }
1036    
1037            /**
1038             * Updates the company's security properties.
1039             *
1040             * @param  companyId the primary key of the company
1041             * @param  authType the company's method of authenticating users
1042             * @param  autoLogin whether to allow users to select the "remember me"
1043             *         feature
1044             * @param  sendPassword whether to allow users to ask the company to send
1045             *         their password
1046             * @param  strangers whether to allow strangers to create accounts register
1047             *         themselves in the company
1048             * @param  strangersWithMx whether to allow strangers to create accounts
1049             *         with email addresses that match the company mail suffix
1050             * @param  strangersVerify whether to require strangers who create accounts
1051             *         to be verified via email
1052             * @param  siteLogo whether to allow site administrators to use their own
1053             *         logo instead of the enterprise logo
1054             * @throws SystemException if a system exception occurred
1055             */
1056            public void updateSecurity(
1057                            long companyId, String authType, boolean autoLogin,
1058                            boolean sendPassword, boolean strangers, boolean strangersWithMx,
1059                            boolean strangersVerify, boolean siteLogo)
1060                    throws SystemException {
1061    
1062                    PortletPreferences preferences = PrefsPropsUtil.getPreferences(
1063                            companyId);
1064    
1065                    try {
1066                            preferences.setValue(
1067                                    PropsKeys.COMPANY_SECURITY_AUTH_TYPE, authType);
1068                            preferences.setValue(
1069                                    PropsKeys.COMPANY_SECURITY_AUTO_LOGIN,
1070                                    String.valueOf(autoLogin));
1071                            preferences.setValue(
1072                                    PropsKeys.COMPANY_SECURITY_SEND_PASSWORD,
1073                                    String.valueOf(sendPassword));
1074                            preferences.setValue(
1075                                    PropsKeys.COMPANY_SECURITY_STRANGERS,
1076                                    String.valueOf(strangers));
1077                            preferences.setValue(
1078                                    PropsKeys.COMPANY_SECURITY_STRANGERS_WITH_MX,
1079                                    String.valueOf(strangersWithMx));
1080                            preferences.setValue(
1081                                    PropsKeys.COMPANY_SECURITY_STRANGERS_VERIFY,
1082                                    String.valueOf(strangersVerify));
1083                            preferences.setValue(
1084                                    PropsKeys.COMPANY_SECURITY_SITE_LOGO, String.valueOf(siteLogo));
1085    
1086                            preferences.store();
1087                    }
1088                    catch (IOException ioe) {
1089                            throw new SystemException(ioe);
1090                    }
1091                    catch (PortletException pe) {
1092                            throw new SystemException(pe);
1093                    }
1094            }
1095    
1096            protected Company checkLogo(long companyId)
1097                    throws PortalException, SystemException {
1098    
1099                    Company company = companyPersistence.findByPrimaryKey(companyId);
1100    
1101                    long logoId = company.getLogoId();
1102    
1103                    if (logoId <= 0) {
1104                            logoId = counterLocalService.increment();
1105    
1106                            company.setLogoId(logoId);
1107    
1108                            company = companyPersistence.update(company, false);
1109                    }
1110    
1111                    return company;
1112            }
1113    
1114            protected void updateAccount(
1115                            Company company, String name, String legalName, String legalId,
1116                            String legalType, String sicCode, String tickerSymbol,
1117                            String industry, String type, String size)
1118                    throws SystemException {
1119    
1120                    Date now = new Date();
1121    
1122                    Account account = accountPersistence.fetchByPrimaryKey(
1123                            company.getAccountId());
1124    
1125                    if (account == null) {
1126                            long accountId = counterLocalService.increment();
1127    
1128                            account = accountPersistence.create(accountId);
1129    
1130                            account.setCompanyId(company.getCompanyId());
1131                            account.setCreateDate(now);
1132                            account.setUserId(0);
1133                            account.setUserName(StringPool.BLANK);
1134    
1135                            company.setAccountId(accountId);
1136    
1137                            companyPersistence.update(company, false);
1138                    }
1139    
1140                    account.setModifiedDate(now);
1141                    account.setName(name);
1142                    account.setLegalName(legalName);
1143                    account.setLegalId(legalId);
1144                    account.setLegalType(legalType);
1145                    account.setSicCode(sicCode);
1146                    account.setTickerSymbol(tickerSymbol);
1147                    account.setIndustry(industry);
1148                    account.setType(type);
1149                    account.setSize(size);
1150    
1151                    accountPersistence.update(account, false);
1152            }
1153    
1154            protected void updateVirtualHost(long companyId, String virtualHostname)
1155                    throws CompanyVirtualHostException, SystemException {
1156    
1157                    if (Validator.isNotNull(virtualHostname)) {
1158                            try {
1159                                    VirtualHost virtualHost = virtualHostPersistence.findByHostname(
1160                                            virtualHostname);
1161    
1162                                    if ((virtualHost.getCompanyId() != companyId) ||
1163                                            (virtualHost.getLayoutSetId() != 0)) {
1164    
1165                                            throw new CompanyVirtualHostException();
1166                                    }
1167                            }
1168                            catch (NoSuchVirtualHostException nsvhe) {
1169                                    virtualHostLocalService.updateVirtualHost(
1170                                            companyId, 0, virtualHostname);
1171                            }
1172                    }
1173                    else {
1174                            try {
1175                                    virtualHostPersistence.removeByC_L(companyId, 0);
1176                            }
1177                            catch (NoSuchVirtualHostException nsvhe) {
1178                            }
1179                    }
1180            }
1181    
1182            protected void validate(long companyId, String name)
1183                    throws PortalException, SystemException {
1184    
1185                    Group group = groupLocalService.fetchGroup(companyId, name);
1186    
1187                    if ((group != null) || Validator.isNull(name)) {
1188                            throw new AccountNameException();
1189                    }
1190            }
1191    
1192            protected void validate(String webId, String virtualHostname, String mx)
1193                    throws PortalException, SystemException {
1194    
1195                    if (Validator.isNull(virtualHostname)) {
1196                            throw new CompanyVirtualHostException();
1197                    }
1198                    else if (virtualHostname.equals(_DEFAULT_VIRTUAL_HOST) &&
1199                                     !webId.equals(PropsValues.COMPANY_DEFAULT_WEB_ID)) {
1200    
1201                            throw new CompanyVirtualHostException();
1202                    }
1203                    else if (!Validator.isDomain(virtualHostname)) {
1204                            throw new CompanyVirtualHostException();
1205                    }
1206                    else {
1207                            try {
1208                                    VirtualHost virtualHost = virtualHostPersistence.findByHostname(
1209                                            virtualHostname);
1210    
1211                                    long companyId = virtualHost.getCompanyId();
1212    
1213                                    Company virtualHostnameCompany =
1214                                            companyPersistence.findByPrimaryKey(companyId);
1215    
1216                                    if (!virtualHostnameCompany.getWebId().equals(webId)) {
1217                                            throw new CompanyVirtualHostException();
1218                                    }
1219                            }
1220                            catch (NoSuchVirtualHostException nsvhe) {
1221                            }
1222                    }
1223    
1224                    if (Validator.isNull(mx)) {
1225                            throw new CompanyMxException();
1226                    }
1227                    else if (!Validator.isDomain(mx)) {
1228                            throw new CompanyMxException();
1229                    }
1230            }
1231    
1232            protected void validateLocales(String locales) throws PortalException {
1233                    String[] localesArray = StringUtil.split(locales, StringPool.COMMA);
1234    
1235                    for (String locale : localesArray) {
1236                            if (!ArrayUtil.contains(PropsValues.LOCALES, locale)) {
1237                                    throw new LocaleException();
1238                            }
1239                    }
1240            }
1241    
1242            private static final String _DEFAULT_VIRTUAL_HOST = "localhost";
1243    
1244            private static Log _log = LogFactoryUtil.getLog(
1245                    CompanyLocalServiceImpl.class);
1246    
1247    }