1   /**
2    * Copyright (c) 2000-2007 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.blogs.service.impl;
24  
25  import com.liferay.counter.service.CounterLocalServiceUtil;
26  import com.liferay.portal.PortalException;
27  import com.liferay.portal.SystemException;
28  import com.liferay.portal.kernel.search.Hits;
29  import com.liferay.portal.kernel.util.ArrayUtil;
30  import com.liferay.portal.kernel.util.ContentTypes;
31  import com.liferay.portal.kernel.util.GetterUtil;
32  import com.liferay.portal.kernel.util.OrderByComparator;
33  import com.liferay.portal.kernel.util.StringMaker;
34  import com.liferay.portal.kernel.util.Validator;
35  import com.liferay.portal.lucene.LuceneFields;
36  import com.liferay.portal.lucene.LuceneUtil;
37  import com.liferay.portal.model.Group;
38  import com.liferay.portal.model.User;
39  import com.liferay.portal.model.impl.ResourceImpl;
40  import com.liferay.portal.service.ResourceLocalServiceUtil;
41  import com.liferay.portal.service.persistence.GroupUtil;
42  import com.liferay.portal.service.persistence.UserUtil;
43  import com.liferay.portal.theme.ThemeDisplay;
44  import com.liferay.portal.util.PortalUtil;
45  import com.liferay.portlet.blogs.EntryContentException;
46  import com.liferay.portlet.blogs.EntryDisplayDateException;
47  import com.liferay.portlet.blogs.EntryTitleException;
48  import com.liferay.portlet.blogs.NoSuchCategoryException;
49  import com.liferay.portlet.blogs.model.BlogsCategory;
50  import com.liferay.portlet.blogs.model.BlogsEntry;
51  import com.liferay.portlet.blogs.model.BlogsStatsUser;
52  import com.liferay.portlet.blogs.model.impl.BlogsCategoryImpl;
53  import com.liferay.portlet.blogs.service.BlogsStatsUserLocalServiceUtil;
54  import com.liferay.portlet.blogs.service.base.BlogsEntryLocalServiceBaseImpl;
55  import com.liferay.portlet.blogs.service.persistence.BlogsCategoryUtil;
56  import com.liferay.portlet.blogs.service.persistence.BlogsEntryFinder;
57  import com.liferay.portlet.blogs.service.persistence.BlogsEntryUtil;
58  import com.liferay.portlet.blogs.service.persistence.BlogsStatsUserUtil;
59  import com.liferay.portlet.blogs.util.Indexer;
60  import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
61  import com.liferay.portlet.ratings.service.RatingsStatsLocalServiceUtil;
62  import com.liferay.portlet.tags.service.TagsAssetLocalServiceUtil;
63  import com.liferay.util.Http;
64  import com.liferay.util.HttpUtil;
65  import com.liferay.util.Normalizer;
66  import com.liferay.util.lucene.HitsImpl;
67  
68  import java.io.IOException;
69  
70  import java.util.Date;
71  import java.util.Iterator;
72  import java.util.List;
73  
74  import org.apache.commons.logging.Log;
75  import org.apache.commons.logging.LogFactory;
76  import org.apache.lucene.document.Document;
77  import org.apache.lucene.index.IndexWriter;
78  import org.apache.lucene.index.Term;
79  import org.apache.lucene.search.BooleanClause;
80  import org.apache.lucene.search.BooleanQuery;
81  import org.apache.lucene.search.Searcher;
82  import org.apache.lucene.search.TermQuery;
83  
84  /**
85   * <a href="BlogsEntryLocalServiceImpl.java.html"><b><i>View Source</i></b>
86   * </a>
87   *
88   * @author Brian Wing Shun Chan
89   * @author Wilson S. Man
90   *
91   */
92  public class BlogsEntryLocalServiceImpl extends BlogsEntryLocalServiceBaseImpl {
93  
94      public BlogsEntry addEntry(
95              long userId, long plid, long categoryId, String title,
96              String content, int displayDateMonth, int displayDateDay,
97              int displayDateYear, int displayDateHour, int displayDateMinute,
98              ThemeDisplay themeDisplay, String[] tagsEntries,
99              boolean addCommunityPermissions, boolean addGuestPermissions)
100         throws PortalException, SystemException {
101 
102         return addEntry(
103             userId, plid, categoryId, title, content, displayDateMonth,
104             displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
105             themeDisplay, tagsEntries, Boolean.valueOf(addCommunityPermissions),
106             Boolean.valueOf(addGuestPermissions), null, null);
107     }
108 
109     public BlogsEntry addEntry(
110             long userId, long plid, long categoryId, String title,
111             String content, int displayDateMonth, int displayDateDay,
112             int displayDateYear, int displayDateHour, int displayDateMinute,
113             ThemeDisplay themeDisplay, String[] tagsEntries,
114             String[] communityPermissions, String[] guestPermissions)
115         throws PortalException, SystemException {
116 
117         return addEntry(
118             userId, plid, categoryId, title, content, displayDateMonth,
119             displayDateDay, displayDateYear, displayDateHour, displayDateMinute,
120             themeDisplay, tagsEntries, null, null, communityPermissions,
121             guestPermissions);
122     }
123 
124     public BlogsEntry addEntry(
125             long userId, long plid, long categoryId, String title,
126             String content, int displayDateMonth, int displayDateDay,
127             int displayDateYear, int displayDateHour, int displayDateMinute,
128             ThemeDisplay themeDisplay, String[] tagsEntries,
129             Boolean addCommunityPermissions, Boolean addGuestPermissions,
130             String[] communityPermissions, String[] guestPermissions)
131         throws PortalException, SystemException {
132 
133         // Entry
134 
135         User user = UserUtil.findByPrimaryKey(userId);
136         long groupId = PortalUtil.getPortletGroupId(plid);
137         categoryId = getCategoryId(user.getCompanyId(), categoryId);
138         Date now = new Date();
139 
140         Date displayDate = PortalUtil.getDate(
141             displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
142             displayDateMinute, user.getTimeZone(),
143             new EntryDisplayDateException());
144 
145         validate(title, content);
146 
147         long entryId = CounterLocalServiceUtil.increment();
148 
149         BlogsEntry entry = BlogsEntryUtil.create(entryId);
150 
151         entry.setGroupId(groupId);
152         entry.setCompanyId(user.getCompanyId());
153         entry.setUserId(user.getUserId());
154         entry.setUserName(user.getFullName());
155         entry.setCreateDate(now);
156         entry.setModifiedDate(now);
157         entry.setCategoryId(categoryId);
158         entry.setTitle(title);
159         entry.setUrlTitle(getUniqueUrlTitle(entryId, groupId, title));
160         entry.setContent(content);
161         entry.setDisplayDate(displayDate);
162 
163         BlogsEntryUtil.update(entry);
164 
165         // Resources
166 
167         if ((addCommunityPermissions != null) &&
168             (addGuestPermissions != null)) {
169 
170             addEntryResources(
171                 entry, addCommunityPermissions.booleanValue(),
172                 addGuestPermissions.booleanValue());
173         }
174         else {
175             addEntryResources(entry, communityPermissions, guestPermissions);
176         }
177 
178         // Statistics
179 
180         BlogsStatsUserLocalServiceUtil.updateStatsUser(
181             entry.getGroupId(), userId, now);
182 
183         // Tags
184 
185         updateTagsAsset(userId, entry, tagsEntries);
186 
187         // Lucene
188 
189         try {
190             Indexer.addEntry(
191                 entry.getCompanyId(), entry.getGroupId(), userId, categoryId,
192                 entryId, title, content);
193         }
194         catch (IOException ioe) {
195             _log.error("Indexing " + entryId, ioe);
196         }
197 
198         // Google
199 
200         pingGoogle(entry, themeDisplay);
201 
202         return entry;
203     }
204 
205     public void addEntryResources(
206             long entryId, boolean addCommunityPermissions,
207             boolean addGuestPermissions)
208         throws PortalException, SystemException {
209 
210         BlogsEntry entry = BlogsEntryUtil.findByPrimaryKey(entryId);
211 
212         addEntryResources(entry, addCommunityPermissions, addGuestPermissions);
213     }
214 
215     public void addEntryResources(
216             BlogsEntry entry, boolean addCommunityPermissions,
217             boolean addGuestPermissions)
218         throws PortalException, SystemException {
219 
220         ResourceLocalServiceUtil.addResources(
221             entry.getCompanyId(), entry.getGroupId(), entry.getUserId(),
222             BlogsEntry.class.getName(), entry.getEntryId(), false,
223             addCommunityPermissions, addGuestPermissions);
224     }
225 
226     public void addEntryResources(
227             long entryId, String[] communityPermissions,
228             String[] guestPermissions)
229         throws PortalException, SystemException {
230 
231         BlogsEntry entry = BlogsEntryUtil.findByPrimaryKey(entryId);
232 
233         addEntryResources(entry, communityPermissions, guestPermissions);
234     }
235 
236     public void addEntryResources(
237             BlogsEntry entry, String[] communityPermissions,
238             String[] guestPermissions)
239         throws PortalException, SystemException {
240 
241         ResourceLocalServiceUtil.addModelResources(
242             entry.getCompanyId(), entry.getGroupId(), entry.getUserId(),
243             BlogsEntry.class.getName(), entry.getEntryId(),
244             communityPermissions, guestPermissions);
245     }
246 
247     public void deleteEntries(long groupId)
248         throws PortalException, SystemException {
249 
250         Iterator itr = BlogsEntryUtil.findByGroupId(groupId).iterator();
251 
252         while (itr.hasNext()) {
253             BlogsEntry entry = (BlogsEntry)itr.next();
254 
255             deleteEntry(entry);
256         }
257     }
258 
259     public void deleteEntry(long entryId)
260         throws PortalException, SystemException {
261 
262         BlogsEntry entry = BlogsEntryUtil.findByPrimaryKey(entryId);
263 
264         deleteEntry(entry);
265     }
266 
267     public void deleteEntry(BlogsEntry entry)
268         throws PortalException, SystemException {
269 
270         // Lucene
271 
272         try {
273             Indexer.deleteEntry(entry.getCompanyId(), entry.getEntryId());
274         }
275         catch (IOException ioe) {
276             _log.error("Deleting index " + entry.getEntryId(), ioe);
277         }
278 
279         // Tags
280 
281         TagsAssetLocalServiceUtil.deleteAsset(
282             BlogsEntry.class.getName(), entry.getEntryId());
283 
284         // Ratings
285 
286         RatingsStatsLocalServiceUtil.deleteStats(
287             BlogsEntry.class.getName(), entry.getEntryId());
288 
289         // Message boards
290 
291         MBMessageLocalServiceUtil.deleteDiscussionMessages(
292             BlogsEntry.class.getName(), entry.getEntryId());
293 
294         // Resources
295 
296         ResourceLocalServiceUtil.deleteResource(
297             entry.getCompanyId(), BlogsEntry.class.getName(),
298             ResourceImpl.SCOPE_INDIVIDUAL, entry.getEntryId());
299 
300         // Entry
301 
302         BlogsEntryUtil.remove(entry.getEntryId());
303     }
304 
305     public int getCategoriesEntriesCount(List categoryIds)
306         throws SystemException {
307 
308         return BlogsEntryFinder.countByCategoryIds(categoryIds);
309     }
310 
311     public List getCompanyEntries(long companyId, int begin, int end)
312         throws SystemException {
313 
314         return BlogsEntryUtil.findByCompanyId(companyId, begin, end);
315     }
316 
317     public List getCompanyEntries(
318             long companyId, int begin, int end, OrderByComparator obc)
319         throws SystemException {
320 
321         return BlogsEntryUtil.findByCompanyId(companyId, begin, end, obc);
322     }
323 
324     public int getCompanyEntriesCount(long companyId) throws SystemException {
325         return BlogsEntryUtil.countByCompanyId(companyId);
326     }
327 
328     public List getEntries(long categoryId, int begin, int end)
329         throws SystemException {
330 
331         return BlogsEntryUtil.findByCategoryId(categoryId, begin, end);
332     }
333 
334     public int getEntriesCount(long categoryId) throws SystemException {
335         return BlogsEntryUtil.countByCategoryId(categoryId);
336     }
337 
338     public BlogsEntry getEntry(long entryId)
339         throws PortalException, SystemException {
340 
341         return BlogsEntryUtil.findByPrimaryKey(entryId);
342     }
343 
344     public BlogsEntry getEntry(long groupId, String urlTitle)
345         throws PortalException, SystemException {
346 
347         return BlogsEntryUtil.findByG_UT(groupId, urlTitle);
348     }
349 
350     public List getGroupEntries(long groupId, int begin, int end)
351         throws SystemException {
352 
353         return BlogsEntryUtil.findByGroupId(groupId, begin, end);
354     }
355 
356     public List getGroupEntries(
357             long groupId, int begin, int end, OrderByComparator obc)
358         throws SystemException {
359 
360         return BlogsEntryUtil.findByGroupId(groupId, begin, end, obc);
361     }
362 
363     public int getGroupEntriesCount(long groupId) throws SystemException {
364         return BlogsEntryUtil.countByGroupId(groupId);
365     }
366 
367     public List getGroupUserEntries(
368             long groupId, long userId, int begin, int end)
369         throws SystemException {
370 
371         return BlogsEntryUtil.findByG_U(groupId, userId, begin, end);
372     }
373 
374     public int getGroupUserEntriesCount(long groupId, long userId)
375         throws SystemException {
376 
377         return BlogsEntryUtil.countByG_U(groupId, userId);
378     }
379 
380     public List getNoAssetEntries() throws SystemException {
381         return BlogsEntryFinder.findByNoAssets();
382     }
383 
384     public List getOrganizationEntries(long organizationId, int begin, int end)
385         throws SystemException {
386 
387         return BlogsEntryFinder.findByOrganizationId(
388             organizationId, begin, end);
389     }
390 
391     public int getOrganizationEntriesCount(long organizationId)
392         throws SystemException {
393 
394         return BlogsEntryFinder.countByOrganizationId(
395             organizationId);
396     }
397 
398     public String getUrlTitle(long entryId, String title) {
399         String urlTitle = String.valueOf(entryId);
400 
401         title = title.trim().toLowerCase();
402 
403         if (Validator.isNull(title) || Validator.isNumber(title) ||
404             title.equals("rss")) {
405 
406             return urlTitle;
407         }
408 
409         title = Normalizer.normalizeToAscii(title);
410 
411         char[] urlTitleCharArray = title.toCharArray();
412 
413         for (int i = 0; i < urlTitleCharArray.length; i++) {
414             char oldChar = urlTitleCharArray[i];
415 
416             char newChar = oldChar;
417 
418             if ((oldChar == '_') || (Validator.isChar(oldChar)) ||
419                 (Validator.isDigit(oldChar))) {
420 
421             }
422             else if (ArrayUtil.contains(_URL_TITLE_REPLACE_CHARS, oldChar)) {
423                 newChar = '_';
424             }
425             else {
426                 return urlTitle;
427             }
428 
429             if (oldChar != newChar) {
430                 urlTitleCharArray[i] = newChar;
431             }
432         }
433 
434         urlTitle = new String(urlTitleCharArray);
435 
436         return urlTitle;
437     }
438 
439     public void reIndex(String[] ids) throws SystemException {
440         long companyId = GetterUtil.getLong(ids[0]);
441 
442         IndexWriter writer = null;
443 
444         try {
445             writer = LuceneUtil.getWriter(companyId);
446 
447             Iterator itr = BlogsEntryUtil.findByCompanyId(companyId).iterator();
448 
449             while (itr.hasNext()) {
450                 BlogsEntry entry = (BlogsEntry)itr.next();
451 
452                 long groupId = entry.getGroupId();
453                 long userId = entry.getUserId();
454                 long categoryId = entry.getCategoryId();
455                 long entryId = entry.getEntryId();
456                 String title = entry.getTitle();
457                 String content = entry.getContent();
458 
459                 try {
460                     Document doc = Indexer.getAddEntryDocument(
461                         companyId, groupId, userId, categoryId, entryId, title,
462                         content);
463 
464                     writer.addDocument(doc);
465                 }
466                 catch (Exception e1) {
467                     _log.error("Reindexing " + entryId, e1);
468                 }
469             }
470         }
471         catch (SystemException se) {
472             throw se;
473         }
474         catch (Exception e2) {
475             throw new SystemException(e2);
476         }
477         finally {
478             try {
479                 if (writer != null) {
480                     LuceneUtil.write(companyId);
481                 }
482             }
483             catch (Exception e) {
484                 _log.error(e);
485             }
486         }
487     }
488 
489     public Hits search(
490             long companyId, long groupId, long userId, long[] categoryIds,
491             String keywords)
492         throws SystemException {
493 
494         Searcher searcher = null;
495 
496         try {
497             HitsImpl hits = new HitsImpl();
498 
499             if (Validator.isNull(keywords)) {
500                 return hits;
501             }
502 
503             BooleanQuery contextQuery = new BooleanQuery();
504 
505             LuceneUtil.addRequiredTerm(
506                 contextQuery, LuceneFields.PORTLET_ID, Indexer.PORTLET_ID);
507 
508             if (groupId > 0) {
509                 LuceneUtil.addRequiredTerm(
510                     contextQuery, LuceneFields.GROUP_ID, groupId);
511             }
512 
513             if (userId > 0) {
514                 LuceneUtil.addRequiredTerm(
515                     contextQuery, LuceneFields.USER_ID, userId);
516             }
517 
518             if ((categoryIds != null) && (categoryIds.length > 0)) {
519                 BooleanQuery categoryIdsQuery = new BooleanQuery();
520 
521                 for (int i = 0; i < categoryIds.length; i++) {
522                     Term term = new Term(
523                         "categoryId", String.valueOf(categoryIds[i]));
524                     TermQuery termQuery = new TermQuery(term);
525 
526                     categoryIdsQuery.add(termQuery, BooleanClause.Occur.SHOULD);
527                 }
528 
529                 contextQuery.add(categoryIdsQuery, BooleanClause.Occur.MUST);
530             }
531 
532             BooleanQuery searchQuery = new BooleanQuery();
533 
534             LuceneUtil.addTerm(searchQuery, LuceneFields.CONTENT, keywords);
535 
536             BooleanQuery fullQuery = new BooleanQuery();
537 
538             fullQuery.add(contextQuery, BooleanClause.Occur.MUST);
539             fullQuery.add(searchQuery, BooleanClause.Occur.MUST);
540 
541             searcher = LuceneUtil.getSearcher(companyId);
542 
543             hits.recordHits(searcher.search(fullQuery), searcher);
544 
545             return hits;
546         }
547         catch (Exception e) {
548             return LuceneUtil.closeSearcher(searcher, keywords, e);
549         }
550     }
551 
552     public BlogsEntry updateEntry(
553             long userId, long entryId, long categoryId, String title,
554             String content, int displayDateMonth, int displayDateDay,
555             int displayDateYear, int displayDateHour, int displayDateMinute,
556             ThemeDisplay themeDisplay, String[] tagsEntries)
557         throws PortalException, SystemException {
558 
559         // Entry
560 
561         User user = UserUtil.findByPrimaryKey(userId);
562         categoryId = getCategoryId(user.getCompanyId(), categoryId);
563         Date now = new Date();
564 
565         Date displayDate = PortalUtil.getDate(
566             displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
567             displayDateMinute, user.getTimeZone(),
568             new EntryDisplayDateException());
569 
570         validate(title, content);
571 
572         BlogsEntry entry = BlogsEntryUtil.findByPrimaryKey(entryId);
573 
574         entry.setModifiedDate(now);
575         entry.setCategoryId(categoryId);
576         entry.setTitle(title);
577         entry.setUrlTitle(
578             getUniqueUrlTitle(entryId, entry.getGroupId(), title));
579         entry.setContent(content);
580         entry.setDisplayDate(displayDate);
581 
582         BlogsEntryUtil.update(entry);
583 
584         // Statistics
585 
586         BlogsStatsUser statsUser = BlogsStatsUserUtil.fetchByG_U(
587             entry.getGroupId(), entry.getUserId());
588 
589         if (statsUser != null) {
590             statsUser.setLastPostDate(now);
591 
592             BlogsStatsUserUtil.update(statsUser);
593         }
594 
595         // Tags
596 
597         updateTagsAsset(userId, entry, tagsEntries);
598 
599         // Lucene
600 
601         try {
602             Indexer.updateEntry(
603                 entry.getCompanyId(), entry.getGroupId(), userId, categoryId,
604                 entryId, title, content);
605         }
606         catch (IOException ioe) {
607             _log.error("Indexing " + entryId, ioe);
608         }
609 
610         // Google
611 
612         pingGoogle(entry, themeDisplay);
613 
614         return entry;
615     }
616 
617     public void updateTagsAsset(
618             long userId, BlogsEntry entry, String[] tagsEntries)
619         throws PortalException, SystemException {
620 
621         TagsAssetLocalServiceUtil.updateAsset(
622             userId, BlogsEntry.class.getName(), entry.getEntryId(), tagsEntries,
623             null, null, null, null, ContentTypes.TEXT_HTML, entry.getTitle(),
624             entry.getTitle(), entry.getTitle(), null, 0, 0);
625     }
626 
627     protected long getCategoryId(long companyId, long categoryId)
628         throws PortalException, SystemException {
629 
630         if (categoryId != BlogsCategoryImpl.DEFAULT_PARENT_CATEGORY_ID) {
631 
632             // Ensure category exists and belongs to the proper company
633 
634             try {
635                 BlogsCategory category =
636                     BlogsCategoryUtil.findByPrimaryKey(categoryId);
637 
638                 if (companyId != category.getCompanyId()) {
639                     categoryId = BlogsCategoryImpl.DEFAULT_PARENT_CATEGORY_ID;
640                 }
641             }
642             catch (NoSuchCategoryException nsfe) {
643                 categoryId = BlogsCategoryImpl.DEFAULT_PARENT_CATEGORY_ID;
644             }
645         }
646 
647         return categoryId;
648     }
649 
650     protected String getUniqueUrlTitle(
651             long entryId, long groupId, String title)
652         throws SystemException {
653 
654         String urlTitle = getUrlTitle(entryId, title);
655 
656         String newUrlTitle = new String(urlTitle);
657 
658         for (int i = 1;; i++) {
659             BlogsEntry entry = BlogsEntryUtil.fetchByG_UT(groupId, newUrlTitle);
660 
661             if ((entry == null) || (entry.getEntryId() == entryId)) {
662                 break;
663             }
664             else {
665                 newUrlTitle = urlTitle + "_" + i;
666             }
667         }
668 
669         return newUrlTitle;
670     }
671 
672     protected void pingGoogle(BlogsEntry entry, ThemeDisplay themeDisplay)
673         throws PortalException, SystemException {
674 
675         if (themeDisplay == null) {
676             return;
677         }
678 
679         Group group = GroupUtil.findByPrimaryKey(entry.getGroupId());
680 
681         String portalURL = PortalUtil.getPortalURL(themeDisplay);
682 
683         if ((portalURL.indexOf("://localhost") != -1) ||
684             (portalURL.indexOf("://127.0.0.1") != -1)) {
685 
686             return;
687         }
688 
689         String layoutURL = PortalUtil.getLayoutURL(themeDisplay);
690 
691         StringMaker sm = new StringMaker();
692 
693         String name = group.getDescriptiveName();
694         //String url = portalURL + layoutURL + "/blogs/" + entry.getUrlTitle();
695         String url = portalURL + layoutURL + "/blogs";
696         String changesURL = portalURL + layoutURL + "/blogs/rss";
697 
698         sm.append("http://blogsearch.google.com/ping?name=");
699         sm.append(HttpUtil.encodeURL(name));
700         sm.append("&url=");
701         sm.append(HttpUtil.encodeURL(url));
702         sm.append("&changesURL=");
703         sm.append(HttpUtil.encodeURL(changesURL));
704 
705         String location = sm.toString();
706 
707         if (_log.isInfoEnabled()) {
708             _log.info("Pinging Google at " + location);
709         }
710 
711         try {
712             String response = Http.URLtoString(sm.toString());
713 
714             if (_log.isInfoEnabled()) {
715                 _log.info("Google ping response: " + response);
716             }
717         }
718         catch (IOException ioe) {
719             _log.error("Unable to ping Google at " + location, ioe);
720         }
721     }
722 
723     protected void validate(String title, String content)
724         throws PortalException {
725 
726         if (Validator.isNull(title)) {
727             throw new EntryTitleException();
728         }
729         else if (Validator.isNull(content)) {
730             throw new EntryContentException();
731         }
732     }
733 
734     private static final char[] _URL_TITLE_REPLACE_CHARS = new char[] {
735         ' ',  '.',  '-',  ',',  '/',  '\\',  '\'',  '\"'
736     };
737 
738     private static Log _log =
739         LogFactory.getLog(BlogsEntryLocalServiceImpl.class);
740 
741 }