
As a Reminder
- This should all work in the latest Liferay 6.1 CE and EE releases.
- Not a lot of clever coding. I'll post the full source to git as part of the final installment and invite you to fork and fix.
- Not a lot of error checking here. If it fails it doesn't end up blowing up, but also doesn't continue. I leave it to your trusty development skills to fix this.
- A lot of this is hard-coded or assumes the English language is being used. You can undo this with basic development skills as well!
- I don't go into excruciating detail about some of the Liferay APIs used here. Javadoc is your friend. Most of the time.
Get a random point in time
1 2 3 4 5 6 7 |
// generate a random calendar within the past year public static Calendar getCal() { Calendar now = Calendar.getInstance(); int rHours = (int) (Math.random() * 8640); now.add(Calendar.HOUR, 0 - rHours); return now; } |
Create a Profile Avatar/Picture
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// A bunch of random gravatar IDs for use when creating new users public static final String[] GRAVATAR_IDS = new String[]{ "205e460b479e2e5b48aec07710c08d50", "c63392ca320086522cf4d55cbf1d3808", "4d346581a3340e32cf93703c9ce46bd4", // and so on }; // fetch a random portrait from gravatar and return its bytes public static byte[] getPortraitBytes() throws Exception { String id = SocialDriverConstants.GRAVATAR_IDS[(int) (Math.random() * (double) SocialDriverConstants.GRAVATAR_IDS.length)]; String urlS = "http://2.gravatar.com/avatar/" + id + "?s=80&d=identicon"; URL url = new URL(urlS); ByteArrayOutputStream bos = new ByteArrayOutputStream(); InputStream in = url.openStream(); byte[] buf = new byte[2048]; int bytesRead; while ((bytesRead = in.read(buf)) != -1) { bos.write(buf, 0, bytesRead); } in.close(); return bos.toByteArray(); } |
SocialDriverConstants class has a bunch of hard-coded user names, job titles, Gravatar picture IDs, industry keywords for Wikipedia searches, and such, used when generating the content. This code fetches a random picture from Gravatar for use when creating new user profiles later on.
Generate Friend Requests
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// generate a friend request and optionally confirm it public static void addSocialRequest( User user, User receiverUser, boolean confirm) throws Exception { SocialRequest socialRequest = SocialRequestLocalServiceUtil.addRequest( user.getUserId(), 0, User.class.getName(), user.getUserId(), 1, StringPool.BLANK, receiverUser.getUserId()); if (confirm) { SocialRequestLocalServiceUtil.updateRequest( socialRequest.getRequestId(), SocialRequestConstants.STATUS_CONFIRM, new ThemeDisplay()); } } |
Creating and assign fake Addresses
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
private static void assignAddressTo(User user) throws SystemException, PortalException { String street = "123 Anystreet"; String city = "Doesnt Matter"; String zip = "12342"; List<Country> countrys = CountryServiceUtil.getCountries(); Country country = countrys.get((int) (Math.random() * (double) countrys.size())); double rnd = Math.random(); if (rnd < .1) { country = CountryServiceUtil.getCountryByName("United States"); } else if (rnd < .2) { country = CountryServiceUtil.getCountryByName("Japan"); } List<Region> regions = RegionServiceUtil.getRegions(country .getCountryId()); long regionId = 0; if (regions != null && !regions.isEmpty()) { regionId = regions.get((int) (Math.random() * (double) regions .size())).getRegionId(); } AddressLocalServiceUtil.addAddress(user.getUserId(), Contact.class.getName(), user.getContactId(), street, "", "", city, zip, regionId, country.getCountryId(), 11002, true, true); } |
11002 is doing there. Addresses can be of different types (e.g. Personal, Business, and Other. 11002 is the constant for Personal. This is defined in Liferay's default SQL data, and not in Java, so I had to hard-code it here.
Setting User Password, bypassing TOU, Father's Middle Name
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// make it easy to login the first time private static void setFirstLogin(String password, User user) throws Exception { UserLocalServiceUtil.updatePortrait(user.getUserId(), getPortraitBytes()); UserLocalServiceUtil.updateLastLogin( user.getUserId(), user.getLoginIP()); UserLocalServiceUtil.updateAgreedToTermsOfUse(user.getUserId(), true); UserLocalServiceUtil.updatePassword(user.getUserId(), password.toLowerCase(), password.toLowerCase(), false, true); UserLocalServiceUtil.updatePasswordReset(user.getUserId(), false); String[] questions = StringUtil.split( PropsUtil.get("users.reminder.queries.questions")); String question = questions[0]; String answer = "1234"; UserLocalServiceUtil.updateReminderQuery( user.getUserId(), question, answer); } |
john.
getPortraitBytes defined earlier.
Randomly assigning some Friends
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// make a fake social network of friends by randomly friending some // people private static void assignRandomFriends(User user) throws Exception { int userCount = UserLocalServiceUtil.getUsersCount(); int friendCount = (int) (Math.random() * (double) userCount); for (int i = 0; i < friendCount; i++) { int frienduser = (int) (Math.random() * (double) userCount); User randUser = UserLocalServiceUtil.getUsers(frienduser, frienduser + 1).get(0); if (randUser.getUserId() == user.getUserId()) continue; if (randUser.isDefaultUser()) continue; boolean confirm = (Math.random() > .4); addSocialRequest(user, randUser, confirm); } } |
addSocialRequest from up above.
Setting up a User's Profile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
// setup a user's public/private page theme, and construct some useful // profile pages private static void setupUserProfile(long companyId, String themeId, Group guestGroup, User user) throws Exception { Group group = user.getGroup(); if (themeId != null && !themeId.isEmpty()) { LayoutSetLocalServiceUtil.updateLookAndFeel( group.getGroupId(), false, themeId, "01", "", false); } // Profile layout Layout layout = addLayout( group, user.getFullName(), false, "/profile", "2_columns_ii"); JournalArticle cloudArticle, assetListArticle; try { cloudArticle = JournalArticleLocalServiceUtil.getLatestArticle (guestGroup.getGroupId(), SocialDriverConstants.CLOUD_ARTICLE_ID); } catch (NoSuchArticleException ex) { cloudArticle = addArticle("/cloud-structure.xml", "/cloud-template.vm", "cloud-article.xml", UserLocalServiceUtil.getDefaultUserId(companyId), guestGroup.getGroupId(), SocialDriverConstants.CLOUD_ARTICLE_ID); } try { assetListArticle = JournalArticleLocalServiceUtil .getLatestArticle(guestGroup.getGroupId(), SocialDriverConstants.ASSETLIST_ARTICLE_ID); } catch (NoSuchArticleException ex) { assetListArticle = addArticle("/assetlist-structure.xml", "/assetlist-template.vm", "assetlist-article.xml", UserLocalServiceUtil.getDefaultUserId(companyId), guestGroup.getGroupId(), SocialDriverConstants.ASSETLIST_ARTICLE_ID); } try { JournalArticleLocalServiceUtil.getLatestArticle(guestGroup .getGroupId(), SocialDriverConstants.EXPERTSLIST_ARTICLE_ID); } catch (NoSuchArticleException ex) { addArticle("/experts-structure.xml", "/experts-template.vm", "experts-article.xml", UserLocalServiceUtil.getDefaultUserId(companyId), guestGroup.getGroupId(), SocialDriverConstants.EXPERTSLIST_ARTICLE_ID); } addPortletId(layout, "1_WAR_socialnetworkingportlet", "column-1"); addPortletId(layout, PortletKeys.REQUESTS, "column-1"); String portletId = addPortletId(layout, PortletKeys.JOURNAL_CONTENT, "column-1"); configureJournalContent( layout, guestGroup, portletId, cloudArticle.getArticleId()); configurePortletTitle(layout, portletId, "Expertise"); addPortletBorder(layout, portletId); addPortletBorder(layout, addPortletId(layout, "2_WAR_socialnetworkingportlet", "column-1")); addPortletBorder(layout, addPortletId(layout, PortletKeys.ACTIVITIES, "column-2")); addPortletBorder(layout, addPortletId(layout, "3_WAR_socialnetworkingportlet", "column-2")); // Expertise layout layout = addLayout(group, "Expertise", false, "/expertise", "2_columns_ii"); addPortletId(layout, "1_WAR_socialnetworkingportlet", "column-1"); addPortletId(layout, PortletKeys.REQUESTS, "column-1"); portletId = addPortletId(layout, PortletKeys.JOURNAL_CONTENT, "column-1"); configureJournalContent( layout, guestGroup, portletId, cloudArticle.getArticleId()); configurePortletTitle(layout, portletId, "Expertise"); addPortletBorder(layout, portletId); portletId = addPortletId(layout, PortletKeys.JOURNAL_CONTENT, "column-2"); configureJournalContent( layout, guestGroup, portletId, assetListArticle.getArticleId()); configurePortletTitle(layout, portletId, user.getFirstName() + "'s " + "Contributions"); addPortletBorder(layout, portletId); // Social layout layout = addLayout(group, "Social", false, "/social", "2_columns_ii"); addPortletId(layout, "1_WAR_socialnetworkingportlet", "column-1"); addPortletId(layout, PortletKeys.REQUESTS, "column-1"); addPortletBorder(layout, addPortletId(layout, "2_WAR_socialnetworkingportlet", "column-1")); addPortletBorder(layout, addPortletId(layout, PortletKeys.ACTIVITIES, "column-2")); addPortletBorder(layout, addPortletId(layout, "3_WAR_socialnetworkingportlet", "column-2")); // Blog layout layout = addLayout(group, "Blog", false, "/blog", "2_columns_ii"); addPortletBorder(layout, addPortletId(layout, PortletKeys.RECENT_BLOGGERS, "column-1")); addPortletBorder(layout, addPortletId(layout, PortletKeys.BLOGS, "column-2")); // Workspace layout layout = addLayout( group, "Workspace", false, "/workspace", "2_columns_i"); addPortletBorder(layout, addPortletId(layout, PortletKeys.RECENT_DOCUMENTS, "column-1")); addPortletBorder(layout, addPortletId(layout, PortletKeys.DOCUMENT_LIBRARY, "column-2")); addPortletId(layout, PortletKeys.CALENDAR, "column-2"); } |
- User's Name (Friendly URL: /profile)
- Expertise (Friendly URL: /expertise)
- Social (Friendly URL: /social)
- Blog (Friendly URL: /blog)
- Workspace (Friendly URL: /workspace)
Programmatically Creating a Liferay User
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
// add a new user to the DB, using random fake data, // and set up their profile pages, and add // them to the right sites, friend a couple of other random users. public synchronized static User addUser(String firstName, long companyId, String themeId, boolean profileFlag) throws Exception { String lastName = getRndStr(SocialDriverConstants.LAST_NAMES); String job = getRndStr(SocialDriverConstants.JOB_TITLES); Group guestGroup = GroupLocalServiceUtil.getGroup( companyId, GroupConstants.GUEST); long[] groupIds; try { // see if there's a demo sales group, and add the user to the // group if so Group salesGroup = GroupLocalServiceUtil.getGroup( companyId, "Sales"); groupIds = new long[]{guestGroup.getGroupId(), salesGroup.getGroupId()}; } catch (Exception ex) { groupIds = new long[]{guestGroup.getGroupId()}; } ServiceContext serviceContext = new ServiceContext(); long[] roleIds; try { // see if we're using social office, and add SO's role to the new // user if so roleIds = new long[]{RoleLocalServiceUtil.getRole(companyId, "Social Office User").getRoleId()}; serviceContext.setScopeGroupId(guestGroup.getGroupId()); } catch (Exception ignored) { roleIds = new long[]{}; } User user = UserLocalServiceUtil.addUser(UserLocalServiceUtil .getDefaultUserId(companyId), companyId, false, firstName, firstName, false, firstName.toLowerCase(), firstName.toLowerCase() + "@liferay.com", 0, "", LocaleUtil.getDefault(), firstName, "", lastName, 0, 0, true, 8, 15, 1974, job, groupIds, new long[]{}, roleIds, new long[]{}, false, serviceContext); assignAddressTo(user); setFirstLogin(firstName, user); assignRandomFriends(user); if (profileFlag) { setupUserProfile(companyId, themeId, guestGroup, user); } return user; } |
- If it finds a Site called "Sales", it'll assign the newly created user to it, in addition to assigning them to the Guest Site. This is because I use a demo group called "Sales" (mimics a typical enterprise sales organization) so I want to add users to it if such a site exists.
- It will also imbue the new user with the "Social Office User" role if such a role exists (and it will, if you are using Social Office).
- Note that Social Office comes with a nice looking theme, so in most cases if you are using SO, you'll not want the theme assignment to happen. There is an option in the UI for this.
- It finally assigns a random address to the user, configures their account to make it easy to login the first time, assigns random friends, and then sets up the new user's profile as defined above.
Get (or create) a random User
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// retrieves a random user from the company. If the randomly chosen user // doesn't exist, create them first public static long getUserId(long companyId, String themeId, boolean profileFlag) throws Exception { User user; String first = getRndStr(SocialDriverConstants.FIRST_NAMES); try { user = UserLocalServiceUtil.getUserByScreenName(companyId, first.toLowerCase()); } catch (NoSuchUserException ex) { user = addUser(first, companyId, themeId, profileFlag); } return user.getUserId(); } |
Removing Stop Words
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// standard list of common english words to eliminate from tags public static final List<String> ENGLISH_STOP_WORDS = Arrays.asList( "a", "an", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"); // remove common tags from the array of passed-in tags public static String[] removeEnglishStopWords(String[] a) { List<String> result = new ArrayList<String>(); for (String as : a) { if (SocialDriverConstants.ENGLISH_STOP_WORDS.contains(as)) continue; if (as.length() < 3) continue; result.add(as); } return result.toArray(new String[result.size()]); } |
User-Generated Content
- Blog Posts
- Wiki Articles
- Forum Posts
- Blog, Wiki comments
- Forum responses
- Blog, Wiki, Forum ratings/votes
Picking terms for Wikipedia Searches
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
// hard-coded set of tags to use when searching wikipedia public static final String[] FAVORED_TAGS = new String[]{ "java", "liferay", "javaee", "ldap", "portal", "content management system", "social networking", "mobile", "android", "cloud computing", "j2ee", "enterprise software", "sharepoint", "single sign on", "gadgets", "open source", "collaboration" }; public static String getRndStr(String[] ar) { return ar[(int) (Math.random() * (double) ar.length)]; } // get some random terms to search for, with no duplicate terms private String[] getRandomTerms(String[] allTerms) { int termCount = 1 + (int) (Math.random() * SocialDriverConstants.MAX_SEARCH_TERMS); List<String> result = new ArrayList<String>(); String term; for (int j = 0; j < termCount; j++) { while (result.contains(term = SocialDriverUtil.getRndStr(allTerms))) { // do nothing } result.add(term); } return (String[]) result.toArray(new String[result.size()]); } |
Fetching articles from wikipedia
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
private static Set<ContentArticle> fetchWikipediaArticles(HttpClient httpclient, String[] terms) throws IOException, JSONException { int hitLength; Set<ContentArticle> result = new HashSet<ContentArticle>(); StringBuilder sb = new StringBuilder(); sb.append("http://en.wikipedia.org/w/api" + ".php?action=query&list=search&format=json&srsearch="); sb.append(HtmlUtil.escapeURL(StringUtil.merge(terms, ","))); sb.append("&srnamespace=0&srwhat=text&srprop=snippet&srlimit="); sb.append(SocialDriverConstants.WIKIPEDIA_MAX_ARTICLE_COUNT); GetMethod get = new GetMethod(sb.toString()); httpclient.executeMethod(get); JSONObject wikis = JSONFactoryUtil.createJSONObject(get .getResponseBodyAsString()); JSONArray qresult = wikis.getJSONObject("query").getJSONArray("search"); hitLength = qresult.length(); for (int k = 0; k < hitLength; k++) { JSONObject hit = qresult.getJSONObject(k); String title = hit.getString("title"); String excerpt = hit.getString("snippet"); if (excerpt == null || excerpt.isEmpty()) continue; String[] words = SocialDriverUtil.removeEnglishStopWords(title .replaceAll("[^A-Za-z0-9]", " ").split("\\s+")); result.add(new ContentArticle(title, excerpt, words)); } return result; } |
ContentArticle ojects that are very simple (just a container for the title, tags, and content of an article, used later on to make the content in Liferay). You'll see how this all comes together in the next blog post in this series.
Creating a Blog Post
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
private void addEntry() throws Exception { Calendar rCal = SocialDriverUtil.getCal(); ServiceContext context = new ServiceContext(); context.setCreateDate(rCal.getTime()); context.setModifiedDate(rCal.getTime()); String cid = contentContainer.getRandomId(); String title = contentContainer.getContentTitle(cid); String content = contentContainer.getContentBody(cid); String[] tags = contentContainer.getContentTags(cid); context.setWorkflowAction(WorkflowConstants.ACTION_PUBLISH); context.setAddGroupPermissions(true); context.setAddGuestPermissions(true); context.setAssetTagNames(tags); context.setCompanyId(companyId); context.setScopeGroupId(groupId); BlogsEntry newEntry = BlogsEntryLocalServiceUtil.addEntry (SocialDriverUtil.getUserId(companyId, themeId, profileFlag), title, "", content, rCal.get(Calendar.MONTH), rCal.get(Calendar.DAY_OF_MONTH), rCal.get(Calendar.YEAR), rCal.get(Calendar.HOUR_OF_DAY), rCal.get(Calendar.MINUTE), false, false, null, false, null, null, null, context); System.out.println("Added blog " + newEntry.getTitle() + " Tags: " + Arrays.asList(tags)); } |
Commenting on a Blog Post
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
private void commentEntry() throws Exception { if (BlogsEntryLocalServiceUtil.getBlogsEntriesCount() <= 0) return; int rand = (int) (Math.random() * (double) BlogsEntryLocalServiceUtil .getBlogsEntriesCount()); BlogsEntry entry = BlogsEntryLocalServiceUtil.getBlogsEntries(rand, rand + 1).get(0); Calendar rCal = SocialDriverUtil.getCal(); long userId = SocialDriverUtil.getUserId(companyId, themeId, profileFlag); ServiceContext context = new ServiceContext(); context.setCreateDate(rCal.getTime()); context.setModifiedDate(rCal.getTime()); context.setCompanyId(companyId); context.setWorkflowAction(WorkflowConstants.ACTION_PUBLISH); context.setAddGroupPermissions(true); context.setAddGuestPermissions(true); context.setScopeGroupId(groupId); MBDiscussion disc = MBDiscussionLocalServiceUtil.getDiscussion (BlogsEntry.class.getName(), entry.getPrimaryKey()); MBMessageLocalServiceUtil.addDiscussionMessage(userId, "Joe Schmoe", context.getScopeGroupId(), BlogsEntry.class.getName(), entry.getPrimaryKey(), disc.getThreadId(), MBThreadLocalServiceUtil.getMBThread(disc .getThreadId()).getRootMessageId(), "Subject of comment", "This is great", context); System.out.println("Commented on Blog " + entry.getTitle()); } |
Voting on a Blog Post
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
private void voteEntry() throws Exception { if (BlogsEntryLocalServiceUtil.getBlogsEntriesCount() <= 0) return; int rand = (int) (Math.random() * (double) BlogsEntryLocalServiceUtil.getBlogsEntriesCount()); BlogsEntry entry = BlogsEntryLocalServiceUtil.getBlogsEntries(rand, rand + 1).get(0); Calendar rCal = SocialDriverUtil.getCal(); long userId = SocialDriverUtil.getUserId(companyId, themeId, profileFlag); ServiceContext context = new ServiceContext(); context.setCreateDate(rCal.getTime()); context.setModifiedDate(rCal.getTime()); context.setCompanyId(companyId); context.setWorkflowAction(WorkflowConstants.ACTION_PUBLISH); context.setAddGroupPermissions(true); context.setAddGuestPermissions(true); context.setScopeGroupId(groupId); PrincipalThreadLocal.setName(userId); RatingsEntryServiceUtil.updateEntry(BlogsEntry.class.getName(), entry.getEntryId(), (int) (Math.random() * 5.0) + 1); System.out.println("Voted on Blog " + entry.getTitle()); } |

