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