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