A Day of Liferay

Staff Blogs 11 marzo 2013 Da James Falkner Staff

[EDIT: The A Day Of Liferay page has a detailed guest schedule. Tune into the webcast on April 9 by visiting the same!].

The best ideas often start with "Hey ya'll, watch this!!" or "Oh boy, this is probably a bad idea".  I hope this is one of them. One of the good ones. In this case I literally invite you to "watch this!".

On April 9, 2013 starting at 1300 GMT, you are invited to join myself and a cadre of many others in our awesome community as we take a virtual trip around the globe, stopping along the way to visit those in our community that make Liferay a great destination for open source technology. This worldwide trip will last for 24 continuous hours, and will make stops in every single continent on the planet save for Antarctica (though there have been downloads of Liferay from The Ice!).
 
It's the people behind the term "Liferay Community" that make it great! But we are all stuck behind keyboards and monitors and are geographically separated for most of the time. So, for this day I hope we can come together to meet interesting people in our community, and learn more about their culture, passions, personalities, and Liferay work that goes on behind the anonymous forum posts and blogs. We'll see screen shares of interesting new ideas, technical and non-technical interviews with prominent community members, Q&A from participants, artistic performances, and much more!
 
We will be using Google+ Hangouts On Air, with full audio and video, and with a lot of different and exciting guests throughout the day. We'll post a full schedule of guests and the times on which they will be on soon (I'm still trying to lure a few more victimsguests, and then I'll update this blog post with a pointer), but you can expect community members from your neighboring timezones to be on during typical working hours for you. Anyone with a device and browser will be able to watch the webcast and interact with the group using various methods.
 
We'll also have a few surprise guests, and will be randomly giving away prizes to participants, so be sure to set aside some time during the webcast to join in! It should be a lot of fun. Plus, you get to see what 24 continuous hours of webcasting does to people. All in the name of community cheeky
 
Don't worry, if you cannot join in the fun on April 9, the entire 24 hours will be recorded. We'll also create a highlight reel to summarize any extra special magic moments that may occur. And thanks in advance to all of the brave guests who will join us on our epic journey. Hope to see you all online April 9-10!

Community Roundup

Staff Blogs 25 febbraio 2013 Da James Falkner Staff

Time for another community roundup!  It's been far too long since the last one, and as usual a lot has been happening in and around our community.  I hope everyone has had a good beginning to the new year, and will find some interesting and useful items below.  Warm up your clickers, and read on!

  • Slides and recordings from last year's autumn Liferay Symposiums can be found on the landing pages for the North America, Europe, Spain, and Italy symposiums.  You may also be interested in the news reported from the symposia, or the awards (my favorite part - recognizing awesome community contributions!).
  • If you rely on Customizable Pages within Liferay, you may find this tidbit from Bin very useful - how to allow users to customize pages, but not too much :)
  • As you know, last year we began the Community Verifier team, to help verify existing issues in Liferay, and clean up our JIRA database of backlogged issues. Once again we are taking a run at the backlog, with a leaderboard and some prizes! If interested, join up in this thread.
  • Thank-yous go to our awesome 2012 Q3 and Q4 top contributorsPrakash Khanchandani, Victor Zorin, Jignesh Vachhani, Jan Geißler, Aniceto P Madrid, and David Kubitza!  These members gave a lot of virtual sweat over the last 6 months!  If you see them about, be sure to give them some gratitude!
  • After a brief hiatus, Radio Liferay has continued, with episodes featuring Jim Hinkey from the Liferay Knowledge Management team, Sam Kong on Security, and most recently the man himself (Olaf) on Liferay's well hidden features.  Spice up your daily commute with gems from our community rock stars!
  • We have had a lot of interest in new user groups recently.  Since the last roundup, we now have groups in Southern California, Colorado Springs, Australia, Japan, Montreal, Poland, and Sweden.  In addition, several user group founders contributed to a Presentation Template, providing a set of nice-looking and relevant slides to use in creating and giving presentations at community meetups.
  • Notable user groups with recent activity include India, Montreal, Netherlands, Japan, and SoCal. Also, check out the UK User Group's recent meetup reports.  They are using Social Office for the group site, and it's looking good!
  • A community Ruby Gem to create and manage Liferay projects?  Yes, please!
  • The Liferay Marketplace is now fully armed and operational. Several notable apps have been published, such as Xtivia's Carousel Portlet, Permeance's Documents and Media Downloader, and Neurones' Property Search Portlet.  Here's a list of all of them, including Liferay's apps.
  • From the releases desk: Liferay Portal 6.1 CE GA3 continues to bake in the oven. Several issues related to PACL have been fixed, hopefully making it possible to publish even more apps on the Marketplace.  Liferay Portal 6.2 is also under active development.  The latest Milestone release (Milestone 4) is undergoing community testing. Watch the Release Dashboard for updates!
  • The Liferay Faces team has been busy since the acquisition of portletfaces.org - check out the latest release, and Neil's interview with Kito Mann, and don't miss the latest release!
  • Nice tip from Snig on how to get rid of Alfresco Share navigation headers when using it with Liferay. Thanks, Snig!
  • Tomas shows us how to run Liferay's built-in unit and integration tests. Of course these are run whenever someone commits, but it's nice to run it for your own projects as well.
  • You may have noticed that when you are filing issues at issues.liferay.com, the ticket type New Feature and Improvement are gone, replaced by a single Feature Request ticket type.  More to come on this, but this is the start of a cool new Community Ideation process we've wanted for a long time, allowing requests to bubble up via socializing of ideas, voting, commenting, etc.  Good things ahead!
  • Accessibility is not trivial, and Liferay has gone to great lengths to make the platform accessible.  Watch Julio navigate a Liferay site blindfolded!
  • AlloyUI has had a storied past with Liferay.  With the launch of version 2.0, it has a new look and feel, a fantastic website, improved documentation, and much more. There's even a new #alloyui IRC channel on FreeNode!
  • You probably saw this, but Milen made some really cool eye candy and shows you the activity in Liferay's source base.  
  • Fun fact of the day: "Liferay, the most popular Java-based content management system, has increased its user base by 44.3% in the last year."  Link.
  • Bitergia has done an interesting analysis of our open source community, looking at Git and JIRA data over the last few years. Of course, the total activity is ramping up as Liferay grows and is used more and more, but more interesting are the quantiles graphs - showing roughly how long it took to resolve tickets opened in a given month.  These and other kinds of metrics are constantly being monitored and used to improve the effectiveness of our open source community.  Look for additional efforts in the future!
  • A Liferay and OSGi combination is a quasi-nirvana state that we are steadily approaching.  Check out Miguel's slides from the Spain Symposium for a brief glimpse into this promising future for modularity in Liferay!  As an example, check out shell-level access with Gogo. I can't wait to ssh into my running Liferay and fool around!
  • The Liferay website underwent an upgrade to 6.1 EE last month.  The site itself didn't change much, but the web team can now concentrate on an information redesign (including our beloved community site!).  Don't worry, your favorite stuff will continue to work as usual!  But better!
  • XMLPortletFactory continues to add awesomeness thanks to its community of developers, and now developers can easily integrate their custom actions with Liferay's Activity Framework.  I continue to bang on the "unappreciated feature drum" when discussing Social activities within Liferay!
  • Tabbed and paginated search results with no javascript.  Thanks Amit!
  • IRC traffic on #liferay has been steadily increasing - at one point last week, we had over 40 people in the chatroom, a record for Liferay. Kudos to all of you who are contributing to our little group!
  • Nick shows us how to use the popular Twitter Bootstrap framework to build responsive layouts within a Liferay site.  Well done!
  • Jorge from Liferay has a remarkable series of posts on Liferay's internal architecture.  The first 5 parts are:  OverviewServices LayerWeb Services, Caching, and Service Builder.  This is a great reference for any new or experienced Liferay developer.
  • NightHacking on Liferay, with Sampsa.  Enough said!
  • We in the community are serious about security.  With the formation of the Community Security Team last year, we have a better way of educating developers and providing source and binary patches for security issues.  In addition, there seems to be a renewed interest in documenting all the ways of hardening Liferay.  Here's a nice post describing how to test for vulnerabilities, and how to protect against them.  There's also a wiki page that shows you additional security best practices.
  • There have been many awesome blog posts and wiki updates, and we try to keep everyone up to date monthly via the Community Pulse newsletter.  If you wish to receive this, sign up here.
  • If you're attending EclipseCon, Portal Tech Days, Congres Intranet, JAX, Gartner PCC, KCDC, Community Leadership Summit, OSCON, or JavaOne this year, please.. stop by and say hi!

That's all I have for you today. Until next time (and hopefully such a time isn't that far out in the future next time!).

Part II: 7Cogs is Dead! Long Live 7Cogs!

Staff Blogs 14 febbraio 2013 Da James Falkner Staff

In the first installment of this series, I showed several (hopefully useful) code snippets demonstrating the programmatic creation of various things in Liferay - pages, portlets, and structured web content, which can be found in the smoldering ashes of the 7Cogs sample data included in Liferay until version 6.1.
 
I am using these snippets in an app that auto-populates a blank Liferay Site with interesting eye candy people and content, useful for showing demos and running tests that require a lot of user-generated content (you can see examples of such content in the third welcome video created for the 6.1 launch).
 
In this blog post, we'll look some of the code that generates the fake users and content.  These snippets build on, but are not not directly copied from, 7Cogs. So quality is most likely decreasing :)  But most of the Liferay logic is derived from 7Cogs.
 

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;
}
 
This method is used when setting the creation date of user-generated content, to simulate that the content was created at some point in the past.  It makes time-based visualizations more interesting!
 

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();
}
 
Now the fun, fragility, and questionable coding begins!  The 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());
    }
}
 
This code links users together through Social Relations (aka Friending).  It will optionally confirm the friend request.  This is used to randomly friend users to make them less lonely and make the social graph appear more interesting.
 

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);
}
 
Here we are randomly creating an Address and assigning it to a user, for later visualization.  You can also see a slight bias for the United States and Japan (you can change this).  10% of the time, the user's address will be in the US.  10% of the time, it will be in Japan.  The other 80% of the time it'll be in a random country in the world (of the countries defined by Liferay).  This is used later when visualizing user's locations.
 
You may be wondering what that hard-coded 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);
}
 
This makes it such that you can log in with the newly created user without having to set password, agree to the terms of use, or set your reminder questions.  The password is set to the user's first name, using all lower-case letters.  So John Smith's password will be john.
 
It also sets a user's profile picture using a random Gravatar ID through the call to 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);
    }
}
 
This picks some random users with which a relationship is established.  It avoids friending the "default" (guest) user, and also avoids friending the user with themselves (which is weird, right?).  It uses the previously defined 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");
}
 
This rather long method is in the spirit of 7Cogs.  It first assigns the user's public pages a theme (lines 7-10) (if this option is chosen in the GUI to be seen later).  It then adds three Web Content Articles (lines 19-52) (each based on a Web Content Template and Structure).  These are special web content articles that I'll show you in the next installment in this series.  These articles, along with some other Liferay portlets (like a calendar, documents and media, recent bloggers, etc), are placed on the user's newly-created 4 profile pages (lines 54-126):
 
  • 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;

}
 
This code creates a new Liferay User.  Some notes:
  • 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();

}
 
This code will pick a random user from the set of defined users in our constants file, and if they don't exist yet, it'll create them (via prior code above).  It is used when creating fake content (blogs, wikis, ratings, comments, etc).
 

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()]);
}
 
This removes common English Stop Words, those that are very common and are useless as tags, such as The or A, or any word that is 2 characters or less, which are pretty useless as tags too.  I'm pretty sure the Big-O performance of this is really bad.
 

User-Generated Content

As part of this app, we also generate a bunch of user content in the form of:
  • Blog Posts
  • Wiki Articles
  • Forum Posts
  • Blog, Wiki comments
  • Forum responses
  • Blog, Wiki, Forum ratings/votes
The content is generated by going out to Wikipedia and fetching articles based on pre-defined search terms.  The title of each article is used to generate a set of tags for the article (ignoring common words like a and the).  The Wikipedia JSON service is used and abused.  This content is cached for use while the generator is running.  Here's how to fetch it:
 

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()]);
}
 
Here we are just picking a random number of random terms from a pre-defined list.  Woo!  Note if you pick too many terms, you won't find anything on Wikipedia (since it's an AND search).  And if you pick too few, you'll get a LOT (which is great, but sometimes searching for java might get you coffee articles, or searching for mobile will get you information about a certain southern US city.  So it's good to have a set of related keywords.
 

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;
}
 
Not much to do with Liferay, but this method queries Wikipedia via its JSON web services, using the supplied String, and established HTTPClient object (this uses Liferay's built-in, old version of the Commons HttpClient).
 
The result of a JSON web service call to Wikipedia is a JSON object (see their docs) containing the results of the search.  You can see what it looks like in your browser.  We grab the title, and break it apart (and remove stop words) and use the result as the tags for the article.  The body is represented by the article's snippet (you can't get the full content from Wikipedia due to usage restrictions).  The result of calling this method is a library of 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.
 
By the way, you can repeatedly call this to get more articles as needed.  It's a good idea to call it a several times (like 10 times with different search terms if you want to generate a LOT of Liferay content).
 

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));
}
 
Now we are back to Liferay APIs.  Here we are randomly picking a date and a user and publishing a blog post using random content and tags from earlier Wikipedia fetches.  This has the side effect of making a new Activity Stream entry, and accumulating Social Activity points!  More on this in the next installment.  We are doing the ServiceBuilder dance here as well, just like before.
 

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());
}
 
This is where things get even more interesting.  Comments in Liferay are created and managed through the MB (Message Board) functionality.  So, you'll see some of those APIs here.  Discussions are associated with content (like blog posts) through the standard className/classPK linkage pattern found throughout Liferay's Asset Framework.  So this code simply picks a random, existing blog post to comment on, and adds the comment to the thread associated with the blog post.  Other content types are very similar (e.g. Wikis, Documents, etc).
 

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());
}
 
Here is how to programmatically find and randomly rate  a random blog post (1 to 5 stars), using the RatingsEntry service.  The deal with the PrincipalThreadLocal on line 19 is that this is how Liferay knows "who" is voting (since voting is typically done in the context of a request/response).
 

Creating, Commenting, and Rating other Content Types

Looks at watch - Wow, where did the time go?  This will have to wait for the next installment, and I will show you how to wrap all of this into a simple Liferay portlet with a horrible yet usable UI for controlling the creation of content and social data.

7Cogs is Dead! Long Live 7Cogs!

Staff Blogs 5 febbraio 2013 Da James Falkner Staff

Ding dong! The witch is dead! Which old witch? The 7Cogs witch!

[EDIT: Part II covers additional stuff beyond this post!).

This isn't news anymore - Starting with 6.1, Liferay replaced the sample data in the bundled Liferay download with a much leaner set of pages and web content that didn't overrun your database with data that was generally the first thing to be removed when starting a new Liferay project. It's not that the sample data was bad, it was just... demo data that shotgunned itself all over your database, and required a database reset to remove.

But there are many gems to be found within the ashes of the good ole 7Cogs. It demonstrated how to programmatically create a lot of useful things in Liferay, so in a series of posts starting with this one I'd like to take a look at some of them, and show how I revived the 7Cogs' corpse and re-used it for something a little more interesting. While I won't cover 100% of what 7Cogs did, I hope you find some of these code snippets useful for your Liferay projects, and the resulting application fun and instructive.  

What did 7Cogs do?

7Cogs consisted of a theme and a hook (along with dependencies on other Liferay plugins like some of the social networking portlets). The main guts of the interesting bits are in the hook. When you first started Liferay 6.0, the hook would determine if it had been run before, and if not, go about its business.

If you look at the hook code from which these snippets evolved, you can see that it did a lot of stuff:

  • Added some Web Content Structures and Templates to the Guest Site
  • Inject a bunch of images from the plugin into the Document Library
  • Configured a custom Theme
  • Add a bunch of pages and portlets to the Guest Site public pages, with friendly URLs
  • Added some Organizations
  • Added a bunch of vocabularies, categories, and tags
  • Added a Mobile theme
  • Added a bunch of Roles and associated Permissions
  • Added several users assigned to those Roles and configured their profile pages
  • Added several documents to each user's document library
  • Caused several of them to befriend each other, and others to have outstanding friend requests
  • Added some Message Board threads, wiki pages, blogs, etc
  • Configured Web Content to be workflow'd with Kaleo
  • Faked a bunch of Social Equity data
  • Link all of the above into the semblance of a "real" live site that you just happened upon during the install

The last bit was what got me interested in this in the first place. At the time, I was interested in showing how Liferay could be used to build a community, but most of my work started on a blank site, and I quickly tired of making users and roles and sites and social features and so forth. 7Cogs was busy being retired into the annals of Liferay history, so I decided to try and refresh it to work on the latest 6.1 release and wrote some helper code around it to give some GUI control over what it was doing. My Frankenstein demo was alive, and I could use it to populate a real site, develop some interesting visualizations around social data, and even watch in real time as things were being generated.

First Things First

Over the course of several blog posts, I will build on previous blog posts with additional snippets, eventually building a system that can create a nice looking site with real-looking users and user-generated content from the web, nicely linked with tags and social activity data, and a couple of interesting visualizations that you can use to drive community site participation in your projects.  A few notes before we get started:

  • This should all work in the latest Liferay 6.1 CE and EE releases.
  • 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!
  • Several Liferay APIs have many arguments that I don't explain in excruciating detail.  For the major service calls I tried to link to the javadoc, which can be your friend. Most of the time.

Getting Contents of a File from a plugin

public static byte[] getBytes(String path) throws Exception {
    return FileUtil.getBytes(getInputStream(path));
}

public static InputStream getInputStream(String path) throws Exception {
    Class<?> clazz = SocialDriverUtil.class;

    return clazz.getResourceAsStream("/resources" + path);
}

public static String getString(String path) throws Exception {
    return new String(getBytes(path));
}

Pretty simple. It just grabs a resource as a stream under the /resources directory in the plugin, and gives you a stream of bytes (getBytes) and can also convert it to a String (getString). These are used later on to retrieve content from the plugin that are housed in external files (resources) within the plugin.

Adding Resources to a Layout

// add a resource to a layout with the portletId.  Yes, this comment is completely worthless.
public static void addResources(Layout layout, String portletId)
    throws Exception {

    String rootPortletId = PortletConstants.getRootPortletId(portletId);

    String portletPrimaryKey = PortletPermissionUtil.getPrimaryKey(
        layout.getPlid(), portletId);

    ResourceLocalServiceUtil.addResources(
        layout.getCompanyId(), layout.getGroupId(), 0, rootPortletId,
        portletPrimaryKey, true, true, true);
}

This method simply adds the resources associated with a portlet to a layout (presumably because you are adding the portlet to the layout, which we are doing later on). Read the section in the documentation regarding Resources and how they interact with the Permissioning system of Liferay.

Adding a Layout (Page) to a Site

// create a new (blank) page for the given group/s public or private layoutset
public static Layout addLayout(
    Group group, String name, boolean privateLayout, String friendlyURL,
    String layoutTemplateId)
    throws Exception {

    ServiceContext serviceContext = new ServiceContext();

    Layout layout = LayoutLocalServiceUtil.addLayout(
        group.getCreatorUserId(), group.getGroupId(), privateLayout,
        LayoutConstants.DEFAULT_PARENT_LAYOUT_ID, name, StringPool.BLANK,
        StringPool.BLANK, LayoutConstants.TYPE_PORTLET, false, friendlyURL,
        serviceContext);

    LayoutTypePortlet layoutTypePortlet =
        (LayoutTypePortlet) layout.getLayoutType();

    layoutTypePortlet.setLayoutTemplateId(0, layoutTemplateId, false);

    addResources(layout, PortletKeys.DOCKBAR);

    return layout;
}

This code creates new pages in a given Group, with default permissions such that everyone can view the page, and assigns them a layout template (such as "2_columns_ii" for the ii'th version of the standard 2-Column layout with a particular percentage width for each column). It also adds the necessary resources of the dockbar to the permissioning system so that you can see the dockbar when viewing the page.

Adding a Portlet to a Layout (Page)

// persist an updated layout entity
public static void updateLayout(Layout layout) throws Exception {
    LayoutLocalServiceUtil.updateLayout(
        layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
        layout.getTypeSettings());
}

// add a portlet to a layout
public static String addPortletId(
    Layout layout, String portletId, String columnId)
    throws Exception {

    LayoutTypePortlet layoutTypePortlet =
        (LayoutTypePortlet) layout.getLayoutType();

    portletId = layoutTypePortlet.addPortletId(
        0, portletId, columnId, -1, false);

    addResources(layout, portletId);
    updateLayout(layout);

    return portletId;
}

The updateLayout method simply flushes the in-memory Layout entity into the Database. If you don't do this, any updates to the layout won't be persisted.

The addPortletId method will add a new portlet to a Layout (page) based on its id (such as PortletKeys.RECENT_BLOGGERS), and place it at the bottom of the specified column (such as "column-1"). You'll see examples of how this is called in a bit.

Setting a custom Title for a Portlet

// set a custom title for a portlet
public static void configurePortletTitle(
    Layout layout, String portletId, String title)
    throws Exception {

    PortletPreferences portletSetup =
        PortletPreferencesFactoryUtil.getLayoutPortletSetup(
            layout, portletId);

    portletSetup.setValue("portletSetupUseCustomTitle", String.valueOf(Boolean.TRUE));
    portletSetup.setValue("portletSetupTitle_en_US", title);

    portletSetup.store();
}

This method updates the displayed title of the portlet. Before you will see the title, you'll need to ensure the portlet is showing its borders.

Showing a Portlet's Borders

// set a portlet to show its borders
public static void addPortletBorder(Layout layout, String portletId)
    throws Exception {

    PortletPreferences portletSetup =
        PortletPreferencesFactoryUtil.getLayoutPortletSetup(
            layout, portletId);

    portletSetup.setValue(
        "portletSetupShowBorders", String.valueOf(Boolean.TRUE));

    portletSetup.store();
}

This method simply turns on the "Show Borders" option for a potlet on a given layout, so that its title is shown, and the portlet gets a rectilinear border around it. Like its configurePortletTitle cousin, it does this by programmatically setting the Portlet's preferences.

That's it for the basics of constructing pages and adding portlets. Now, let's take a look at how we can programmatically create structured Web Content.

Working with Structured Web Content

My demo requires some web content based on structures and templates. The structure (written in xml) and template (Velocity template) are stored externally (hence the need for the previous methods to retrieve files from the plugin).  You'll see what these look like in a later post, but you can always take any of your own articles and download them via the Web Content Editor GUI to see what they look like.  Here are the relevant bits:

Populating a Localization Map

public static void setLocalizedValue(Map<Locale, String> map, String value) {
    Locale locale = LocaleUtil.getDefault();

    map.put(locale, value);

    if (!locale.equals(Locale.US)) {
        map.put(Locale.US, value);
    }
}

This adds a string into a map based on your default locale, and populates the Locale.US value as well if you're not running in that locale. These maps are used when setting the title of web content and other various places where something can take on different, localized values depending on the runtime locale.

Adding a Web Content Structure

Now we are getting somewhere!

public static JournalStructure addJournalStructure(
    long userId, long groupId, String title, String fileName)
    throws Exception {

    Map<Locale, String> nameMap = new HashMap<Locale, String>();

    setLocalizedValue(nameMap, title);

    Map<Locale, String> descriptionMap = new HashMap<Locale, String>();

    setLocalizedValue(descriptionMap, title);

    String xsd = getString(fileName);

    ServiceContext serviceContext = new ServiceContext();

    serviceContext.setAddGroupPermissions(true);
    serviceContext.setAddGuestPermissions(true);

    try {
        JournalStructureLocalServiceUtil.deleteStructure(groupId, title);
    } catch (Exception ex) {
        System.out.println("Ignoring " + ex.getMessage());
    }
    return JournalStructureLocalServiceUtil.addStructure(
        userId, groupId, title, false, StringPool.BLANK, nameMap,
        descriptionMap, xsd, serviceContext);
}

This adds a new Structure, scoped to the specified Group, created by the specified user, with the specified title, whose contents come from the specified fileName. Note the bit with ServiceContext -- this creates the structure with the default permissions (VIEW) so that you can see it as a guest user or as a member of the group. Also, this method first tries to delete the structure if it already exists (and ignores it if there is a failure in doing so, sorry!).

Adding a Web Content Template

public static JournalTemplate addJournalTemplate(
    long userId, long groupId, String title, String structureId, String fileName)
    throws Exception {

    Map<Locale, String> descriptionMap = new HashMap<Locale, String>();

    setLocalizedValue(descriptionMap, "ATemplate");

    Map<Locale, String> nameMap = new HashMap<Locale, String>();

    setLocalizedValue(nameMap, "ATemplate");

    String xsl = getString(fileName);

    ServiceContext serviceContext = new ServiceContext();

    serviceContext.setAddGroupPermissions(true);
    serviceContext.setAddGuestPermissions(true);

    try {
        JournalTemplateLocalServiceUtil.deleteTemplate(groupId, title);
    } catch (Exception ex) {
        System.out.println("Ignoring " + ex.getMessage());

    }
    return JournalTemplateLocalServiceUtil.addTemplate(
        userId, groupId, title, false, structureId, nameMap,
        descriptionMap, xsl, true, "vm", false, false, StringPool.BLANK,
        null, serviceContext);
}

This one is similar to the structure one. The names used here (like "ATemplate") don't really matter. We do the same ServiceContext shenanigans as in the code for adding structures. Note the "vm" - this specifies that the language of the template is velocity (you can use others, such as freemarker).

Adding a Web Content Article

public static JournalArticle addJournalArticle(
    long userId, long groupId, String title, String fileName,
    String structureId, String templateId,
    ServiceContext serviceContext)
    throws Exception {

    String content = getString(fileName);

    serviceContext.setAddGroupPermissions(true);
    serviceContext.setAddGuestPermissions(true);
    serviceContext.setWorkflowAction(WorkflowConstants.ACTION_PUBLISH);
    Map<Locale, String> titleMap = new HashMap<Locale, String>();

    setLocalizedValue(titleMap, title);
    try {
        JournalArticleLocalServiceUtil.deleteArticle(groupId, title, serviceContext);
    } catch (Exception ex) {
        System.out.println("Ignoring " + ex.getMessage());
    }

    return JournalArticleLocalServiceUtil.addArticle(
        userId, groupId, 0, 0, title, false,
        JournalArticleConstants.VERSION_DEFAULT, titleMap, null,
        content, "general", structureId, templateId, StringPool.BLANK,
        1, 1, 2008, 0, 0, 0, 0, 0, 0, 0, true, 0, 0, 0, 0, 0, true,
        true, false, StringPool.BLANK, null, null, StringPool.BLANK,
        serviceContext);
}

Here we are adding an article based on the specified structure and template. We also do the same "delete first" thing to avoid throwing exceptions. There are a lot of arguments to the addArticle method at the bottom. Please refrain from giggling!  You can read all about it in the javadoc.

Causing a given Web Content Display Portlet to display a Web Content Article

// configure a web content display to show a specific article
public static void configureJournalContent(
    Layout layout, Group group, String portletId, String articleId)
    throws Exception {

    PortletPreferences portletSetup =
        PortletPreferencesFactoryUtil.getLayoutPortletSetup(
            layout, portletId);

    if (group == null) {
        portletSetup.setValue("groupId", String.valueOf(layout.getGroupId()));
    } else {
        portletSetup.setValue("groupId", String.valueOf(group.getGroupId()));
    }
    portletSetup.setValue("articleId", articleId);

    portletSetup.store();
}

Pretty basic, it just set's the Web Content Portlets preferences to show the given article. No error checking to ensure that the portlet is actually a web content article either. Whee!

What's Next?

At this point, we have seen how to programmatically create pages, adding and configuring portlets on those pages, creating web content, and displaying web content. In the next installment of this 7Cogs post-mortem, we'll see how we can have fun creating fake users, great-looking profiles for those users, and very real-looking user-generated content based on actual web content from Wikipedia, and put a simple UI on top. Finally, we'll take a look at how to generate and some interesting visualizations of Liferay's social data and explain how these can be used to drive your own communities using Liferay. Stay tuned!

Liferay now available on Windows Azure

Staff Blogs 24 gennaio 2013 Da James Falkner Staff

One of Liferay's key strengths has always been its flexibility.  This stems from Liferay starting out as a consultant-based, services-oriented company.  Every customer had different requirements that were never envisioned as part of the product.  Each time a new requirement was met, facilities were developed to ensure that other requirements in that same area could be met in the future.  This result can be seen both in the underlying frameworks included in the software, and in the myriad sites built on Liferay.

Deployment requirements are no different, and Liferay is built to work with virtually any mainstream operating system, database, application server, front-end framework, and other ancillary services required of a modern web platform.  However, fitting together and maintaining all of those components can be tricky at times, and so to continue the tradition of flexibility, Liferay has partnered with a number of hosting providers to make it easy to deploy and maintain Liferay on premises and in the cloud, using the infrastructure that makes the most sense for your needs.

One of the benefits to us as community members is that our hosting partners get to know Liferay rather well, when designing cloud deployment models around it.  They've even discovered bugs and suggested improvements for Liferay itself!  They also get to know cloud infrastucture providers, which brings me to the point of this post: to let you all know that BitNami, a Liferay Hosting Partner, is now producing and maintaining Liferay images for use on Microsoft's Azure cloud, through their alliance with Microsoft Open Technologies. With Microsoft's VM Depot ("a community-driven catalog of open source virtual machine images for Windows Azure", as Gianugo puts it), you can launch and maintain Liferay instances directly on Azure, and combine it with many other available apps.

It's pretty cool for a number of reasons:

  • The BitNami Liferay stack includes a pre-configured and pre-wired Liferay stack including Ubuntu, Apache Tomcat, MySQL, and more, directly deployable onto Windows Azure.
  • Microsoft's VM Depot also includes a bunch of other open technologies that could be combined with Liferay, through your ability to remix applications and publish the result as a new image on the depot (Microsoft embracing Open Source?  No way!).
  • VM Depot images can later be used by production deployments on the public Azure cloud, with little or no effort (but at that point presumably one would have to pay for that).  So the VM Depot is a great proving ground for Liferay and other open source.
  • It's free!  As in beer!

I am particularly excited to see BitNami taking the initiative to seed the depot with Liferay and other open source.  BitNami started with Liferay 4.3.0 over 5 years ago, and has been a champion of open source even longer.  Hopefully we can all benefit from this new addition to the Liferay deployment ecosystem.  To get started, check out the BitNami Liferay Azure stack!

Community Release Dashboard

Staff Blogs 8 gennaio 2013 Da James Falkner Staff

Everyone knows of Liferay's flagship software product, Liferay Portal, but Liferay actually develops and releases many other products in the Liferay ecosystem. At any one time, development is occurring on all of these products in one way or another, but most people don't learn of these other products until they show up in a press release or are otherwise waved in the air when they are released.

One of my goals as your community manager is to give you the tools and guidance you need to stay up to date with the various happenings within our community, in particular those happenings related to development of Liferay software. There are many ways to do this, and today you have another tool in your arsenal. But before describing it, I wanted to quickly run down the ways in which you can get involved with the development of software in the community, from the bottom to the top.

Source Code

At the lowest level of any open source project is the source code itself, where the rubber meets the road, and where daily (even hourly) changes are exposed. Liferay's source code is managed using the Git source code control system system, and its home lies on Github.com. All of Liferay's open source projects are house here, including Liferay Portal, AlloyUI, Liferay IDE, Liferay Plugins, Liferay's Official Documentation, Liferay Faces, Maven Support, and others.

Developers wishing to get involved can visit the Development wiki pages to set up their own personal development environment, learn the code, and subscribe ("watch") the git repository to receive notifications of any source code change by other developers in the community. Liferay's engineering team strives to make source code commits and associated messages as easy to understand as possible, but it does require a fair amount of development experience to understand what goes on under the hood!

JIRA

Tracking a large software development project like Liferay requires additional tooling above the source code itself. This is where JIRA is used to track bugs, new features, and other program management-related tasks in the form of tickets (or issues). This happens on the aptly-named issues.liferay.com JIRA instance.

Liferay uses JIRA for many different things. Of course, Liferay users are always encouraged to report bugs, and submit new features via JIRA (more on this "idea generation" is coming, as discussed at a recent Liferay Community Leadership Team meetup). Community contributions also flow through JIRA, in the form of "Contributed Solution" and "Community Resolved" states for each contribution.

If you watch the activity stream of items being created and edited, you can see what's happening, in a more human-friendly fashion. Various ticket types are created (such as bugs or New Improvements or Stories), but that can also quickly get overwhelming (there are upwards of 200-300 activities per day here!).

Community Development Board

Of course, source code and ticket activity streams are a very low-level, fine-grained way to participate or observe an open source project, so recently Liferay's engineering and product management teams have begun using a higher-level way to manage and track project changes. For each release of Liferay there exists a Development Board which shows you a quick summary of upcoming (TODO) items, items in progress, and completed items, in terms of New Features and Stories. Here's the development board for the next release, Liferay Portal 6.2. You can read more about this board in my previous blog post to get an idea of the information one can glean from this way of looking at things.

Releases

This brings us to the latest addition in the array of tools you can use to see what's happening. Many of you have requested information on what exactly Liferay has released, or will release in the future, without getting bogged down in the details of individual features or bugs. In fact, Jorge Ferrer (our VP of Engineering) asked me for this soon after I started at Liferay. Paraphrased: "we need a quick, reverse-chronological listing of Liferay releases, with relevant links, so that people can see what's available and get details about each release!" The new Release Dashboard aims to fulfill this gap.

It's a pretty simple Asset Publisher-driven list of releases, grouped by "Past, Current, and Next" buckets. Most importantly, you can get at all of the relevant links (download, issue trackers, and more importantly source code for open source releases) without having to dig deep into liferay.org. In addition, each release has brief release notes, with information about installation, upgrade, support, and other important information that one cannot see by simply looking at a list of "issues fixed". You'll find the Releases link on the left side of the community homepage.

You can check this list regularly, or refer to it when you need quick links for a particular release. As new releases are planned, or released, or retired, this list will be updated. You can also subscribe to its RSS feed if you are into that sort of thing. As releases are "promoted" from "Next" to "Current", and later to "Past", this will be reflected in the list and the feed.

Release Dates

You will also notice that each release has an associated date. For releases that have not yet occurred, you'll find a best guess estimate based on Liferay's desire to release new Portal technology releases every 12-18 months. As usual, these dates are not guaranteed and subject to change. As we get closer to a release date, these dates will be updated to reflect the latest estimate, and if a date is later expected to be "missed", notes will be added to the details section explaining why, and the expected date will be updated.

Milestones1

Liferay has made a lot of changes to its release process over the last few years. New in this cycle is the release of what are called Milestone builds. A Milestone build is a full (pre)release of the Liferay Platform, giving us in the community a chance to try out new features, or discover new bugs before the general availability (GA) release. This is in stark contrast to prior releases, where you only got a Beta release, a month or so before the final release, leaving Liferay very little time to correct anything before release.

This is a really great way to get ahead of the release curve, and discover if the upcoming release is going to meet your needs, and if not, provide that feedback much earlier in the release cycle. In addition, you'll find responsible engineers for various areas of Liferay much more responsive, as they are not in super-crunch-before-release mode. Check out the latest Milestone 3 release and give Liferay your feedback, to help make future releases much better than in the past!

Enterprise Edition

You'll also notice in this list several Enterprise Editions (e.g. Liferay Portal EE, Social Office EE, and Liferay Developer Studio) - the purpose of doing this is to let people know that there are commercially-supported release offerings from Liferay, and if you are looking for that, you don't have to dig into the website to find them.

Plugins

With the advent of the Liferay Marketplace, plugins that are developed by Liferay have been decoupled from the main platform releases, and so you won't find each individual plugin listed on the dashboard. However, plugins continue to be improved, and you can stay informed by watching each plugin's Marketplace landing page (here's the one for Solr), where you'll find version history, release notes for each release, and other information about the plugins. As new platform releases are made, plugins will be revised to incorporate any needed changes, or new features, for the new platform release.

If you find this useful, or have any suggestions, let me know in comments below. We have a lot of other improvements coming this year for our awesome community, and I look forward to seeing what we as a community can do together!

 

1By the way, another goal of these Milestones is to refine the process by which Liferay executes a release. Each Milestone becomes easier to release, as we refine the pipeline from developer's fingers to your download. This will help Liferay meet its expected release dates much easier than before.

What Do You Think?

Staff Blogs 19 dicembre 2012 Da James Falkner Staff

What do you think?

This refrain is commonly found in forum posts, emails, and other postings throughout our community, both from employees of Liferay and its wider open source community.  It's important to be a better listener than a better talker, and to that end we in the community (and specifically your Community Leadership Team) are always asking this question, in order to gauge how best to serve.
 
One important facet of any community is to encourage new members as much as possible, both in a technical sense and in a motivational sense.  If you know precisely what motivates one to participate and/or contribute, you can tailor the resources in the community to target that motivation and efficiently bring new blood into the fold.  To that end, last year, an interesting question was posed.  "What motivates our community?".  A long discussion ensued, and we came to the conclusion that we don't really know, but we should ask what people think.  Back in October we did just that: we launched the 2012 Liferay Community Survey, using the questions developed by some of our most active community members.
 
I thought you might be interested in the results from this survey, so have a look.  I posted the full results of each question, but what follows are some highlights and some of the actions we are taking to address what we found.  We also discussed this in detail at the most recent Community Leadership Team meeting, and several members also provided valuable insight which I included below.
 
One caveat: this is not a scientifically accurate survey.  There's probably some unintended bias in the questions, and some leading questions, but we tried hard to come up with good questions to address what we wanted to know most.  If you have any ideas for future surveys, feel free to share here or in the forums.  Also, as Ryan correctly points out, correlation does not imply causation.  The number of rings in a tree trunk grows each year, as does the S&P 500, but one does not cause the other!  So keep that in mind when drawing conclusions.  Now, on with the show!
 

Survey Results

We had 142 respondents this time around, which I was personally happy with [see full results]. Interestingly enough, there were almost 50 people who started the survey but did not finish.  Perhaps the survey was too long, or not interesting enough?  
 

The Basics

No surprises here.  We've seen a nice uptick in community activity in India (check out the India User Group if interested in getting involved) and we've a number of high quality partners active in India as well.  A diverse community is a healthy community, so I would like the see the gender gap closed as much as possible. I believe there is a lot of innovation and missed opportunity from women that are unfortunately locked away in cultural stereotypes.You can read more about Women in Computing, and if you have any input, let's hear it! My 7 year old daughter has already given me an earful from using Liferay :)
 

Discovery

A couple of interesting bits here.
  • How did you discover Liferay?  Note the small percentage of "Educational Institution".  Steve George has been doing some work here to develop a University Outreach package that can be used worldwide to help bring Liferay to university students, and it's a standing item on our quarterly community meetups.  The students and professors gain a new teaching tool, and we of course gain well qualified graduates who will hopefully champion Liferay once they reach the "real world". 
  • How Long have you used Liferay vs. How many years have you contributed to Liferay?  Note the difference (Ryan did).  People have known and/or used Liferay on average about 3-4 years, but only contributed for 1-2 years.  So, there is a 1-2 year time period during which (we hypothesize) people are using and getting to know Liferay, and only then do they start contributing.  1-2 years is a long time to wait for these, and it points at a lack of community contribution on-ramping for new developers (and not just coders).  We in the community are continuing to work on Liferay University, hopefully bringing easy to follow curriculums for new members to understand Liferay and be able to contribute their knowledge and expertise quicker.

Information Sources

Also not a surprise - most of us use the Forums, Wikis, Blogs, and Official Documentation to get information on Liferay.  I'm proud to also see 11% of you get information from the source code itself.  That's a huge (but not only) benefit of open source, right?  So, yay for open source!
 

Project Details

Here we begin to ask some motivational questions.  We started by asking - why do you use Liferay CE and/or EE?  The results are not really a surprise, but its interesting to see the numbers.  The main reason to choose CE over EE for production use is that a project is too small to justify the cost.  That makes sense.  Liferay is used in a wide variety of solutions, from small, one-person web shops to large companies, so not everyone needs the features and benefits of an enterprise edition.  It's also nice to see a nice distribution of answers to the question "Why would you use Liferay EE (vs. CE)?".  Typical reasons for enterprise use.
 
Following this we asked what Liferay's #1 priority should be going forward, and again no major revelation here - quality, quality, quality.  We in the community have made some good progress here with the many special projects (BugSquad, Community Verifier, etc) that directly contribute to quality and usability, and will continue to do so.  Within Liferay's engineering halls, our community-born engineering lead, Jorge Ferrer, has been making a lot of changes and improvements both internally and externally to how Liferay is produced.  On the testing front, check out Manuel's presentation (en Español) from the Spain Symposium on the Liferay test infrastructure.  For documentation (always a crowd favorite), Rich and team are hard at work here. Follow his blog for more detail.  And finally, in order to make more stable and predictable releases, Liferay has already started producing Milestone builds of the next version.  This will give everyone a chance to see the current state of the project and provide early feedback, and allow Liferay to improve its development and release process, to produce high quality, stable, and regular (predictable) builds with certainty, vs. waiting until the last minute to discover some fatal showstopping flaw.
 

Motivations

Ok, here's where it gets interesting.  The first question is "do you contribute to Liferay?".  And then depending on your answer, the survey went down one of two paths.  Path 1 was for people who do contribute (and thankfully the majority of you do!), and asked questions about why you contribute, how much, what kinds, and so forth. Path 2 was for those that said they did not contribute, and we asked why not, etc.
 
 
For those that contribute, it's nice to see that the main motivation is for sharing skills and knowledge, and to "give something back".  Very altruistic, which is also part of the company's mission.  In addition, most people think that they give more than they get, and that others give more than they do.  Most contributions are in the form of knowledge in our forums, community projects, translations, etc.  Some of the less popular items (such as 100 PaperCuts or Liferay University) need a little tender love and care, which I hope we can do going forward.  
 
\
 
On the other hand, for those that do not contribute, the main reasons are lack of time and knowledge. Both of these can be helped by having better documentation, better quality, less of a learning curve, etc, which makes it easier to learn and hopefully result in less time taken to contribute.  So that I think will be a major focus for 2013. 
 

Also interesting to note the "No expected benefit" response.  This is related to another question in the survey, "does your company reward OSS contributions".  
 
Most companies worldwide do not, according to these results. I believe that many companies see OSS participation as something that takes away from an employee's normal duties, and I'd like to encourage all of you working at companies with this outlook to think about the benefits (direct and indirect) of participation.  Not only from the perspective of Liferay and its application within your company, but with your longer term career goals.  Participation and collaborative development is a great way to not only learn new skills, but make new friends and contacts, and feel good about the work that you do.
 
And on a related note: "No expected benefit" and "Takes too long to see a result" go hand-in-hand - some tickets go a long time before eventually being addressed, so people naturally assume they are being ignored, and are not willing to contribute in the future since their prior issues either took forever to be addressed, or not addressed at all.  This is unacceptable for an open source project and we are addressing this with a new Community Contribution Coordination process (more on this in a separate blog post).
 
 
As far as what might motivate one to start (or increase) participating and contributing, not surprisingly "when I have more knowledge" and "when I have more time" are at the top of the list.  Of course, this mirrors the other question "why do you not contribute".  "when I get free (online) training" ranks high as well, and I expect that the coming Liferay University content will address this.  "When I get special liferay.com powers/privileges" was an interesting response.  What kind of powers/privileges do you think might be beneficial?  Some ideas mentioned by the leadership team included the ability to blog on liferay.com (this is in the works, still), and perhaps discounts on sales if you prove your worth by contributing.  These are all ideas that are being explored.  What say you?
 

Other

One other thing caught my eye: almost 75% of you believe contributing and learning Liferay enhances your job opportunities.  This is fantastic, as it aligns nicely with the company's mission of helping others through technology.  If knowing that ServiceLocalUtil bypasses permission checking (vs. ServiceUtil) helps you get a job, then our work is done!

Be sure to check out the full list of questions and results and see if you can draw any conclusions of your own, and feel free to share them here.
 

Conclusions

Overall, the results seem to confirm several things:
  • Most people find out about Liferay outside of academia
  • There is a time gap between finding Liferay and being able to contribute.
  • Most people contribute because they want to share knowledge and give back.
  • Most contributors feel they get more than they give (which is OK!)
  • The biggest hurdle to contribution is lack of time and knowledge.
  • Liferay should focus more on quality, not as much on features.
  • Most companies do not see benefit to OSS participation.
Earlier in this post I mentioned several initiatives already underway to address these (indeed many of these concerns have been brought up before).  Additional things that we could do:
  • Create an open source "beat sheet" - this is a tool that sales people use that give quick summaries of their product vs. their competitors.  In this case, our competitors include companies who rely upon yet do not understand open source and do not encourage employees to contribute, and active users of Liferay who may be apprehensive about contributions for whatever reason.  And BTW - this also applies to Liferay itself!  
  • Incentivize contributions through special privileges like those mentioned by the CLT
  • Make contribution even easier by linking the product to the community more explicitly.  For example, a Bonfire plugin for Liferay (not a browser plugin, or maybe a browser plugin tied to the Liferay server).
If you have additional ideas on how to make our community even better, let's hear them!
 
Finally, we might want to do this survey again next year and see how the numbers change as a result of work done over the year.  
 

Survey Prize Winners

Of course, we had to dangle a small carrot in front of you to take the 10-15 minute survey, and so here is the result:  Prizes! Bear in mind it's not our primary motivator in the community (hey, we're a small company and can't afford it anyway).  The fine folks at Liferay, Componence, and MyOffice24x7 all contributed to the making of this survey and have generously provided the following prizes to three lucky participants!
 

Spy Tank - Winner: Matt Burke

Rover 2.0 App-Controlled Wireless Spy Tank. Faster, smarter, better! Rover 2.0 goes where no app-controlled tank has gone before. Drive it with your iPad, iPhone or iPod touch device, or with Android smart phones and tablets. See in the dark using Rover's built-in night vision. Stream and record live video and stills. Upload videos and stills to Facebook, Youtube and Twitter sites right from the App Control the angle of the video camera remotely.
 

iPad Foosball Table - Winner: Daphné Bellemin

Sure it’s cool to live in an ultra small, super expensive space in a hip city. But you miss out on a lot of stuff, like king sized beds and giant table games. Take foosball for example. There’s no way the real-life version of Chandler and Joey’s apartment on Friends could house one. Unless it was stored in the bathtub and all the other furniture was moved out of the way during play. Luckily, the folks at New Potato Technologies have created this elaborate iPad housing that serves as a full-fledged foosball table, complete with stubby legs and eight two-axis control rods. It looks like it can support up to four players, but how you can cram four people around even the larger-sized iPad is a mystery left for you to figure out.
 

Raspberry Pi - Winner: Venka Reddy

 
The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It’s a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming.
 

2012 Liferay Community Awards

Staff Blogs 29 ottobre 2012 Da James Falkner Staff

I believe it's really important in any community to give credit where credit is due, whenever possible. When you give, even if you don't expect monetary or other material reward, it's nice to be recognized for your selflessness in front of your peers. It makes you feel good to have others recognize your achievements, and it hopefully spurs others to think about what they are good at and how they could potentially help our community by donating a little time and energy.

Last year we began an annual worldwide recognition award called Community Excellence, which was awarded to several of our partners from the Liferay ecosystem that demonstrated their commitment to the community. The award was based not on revenue or "the bottom line" in any way - instead, it was (and continues to be) based on the community impact that the partners have through their participation and contributions (answering on forums, writing blogs, coding bugfixes or improvements, providing translations, evangelism inside their own sphere of influence, etc). Partners have been essential in Liferay's recent growth, and their employees are some of the most active and beneficial members of the open source community.

I received some feedback shortly after recognizing the partners: what about individuals not affiliated with Liferay (the company) or its partner companies? I had no good answer: it was "the way it was done" in the past (through our regional Partner of the Year designation, which does involve measuring financial impact). Of course that's no excuse, and in fact, if you take time out of your day to contribute to a community that isn't part of your "day job", that is in many ways even more valuable, both to the community and to you. These kinds of contributions must be cherished and rewarded heavily, and contributors of this type must similarly be recognized. They have no financial or legal obligation to use and contribute to Liferay, so these selfless individuals form deep bonds within our community that transcend money. They are also often our most vocal critics, which gives us a much-needed shot of unbiased, and usually constructive criticism in order to "see the forest through the trees" and I believe help advance Liferay in directions unforeseen by those "in the know".

Therefore, I am honored to present this year's community awards to both partners AND individuals!

What We Measured

The actual, super-secret formula must never be revealed (only Ray has the super-secret key), and has been tweaked slightly this year, but the formula involves several (over 20) contribution types, including the obvious ones like helpful forum posts (answers) and code contributions, but other non-obvious, yet highly valuable community metrics, and consideration for external activity such as community evangelism. For the 2012 awards, we considered activity that occured between midnight, September 30th, 2011 and midnight, October 1st, 2012.

Individual Contributors of the Year

 

Hitoshi Ozawa

Hitoshi has been instrumental on our forums with over 6600 lifetime posts, and has been really helpful getting new folks up and over the typical learning curve one experiences, especially with our earlier versions. He also participates in BugSquad and Community Verifier, providing much-needed contributions to our issue database. Finally, earlier this year, Hitoshi was awarded a quarterly contributor award which you can read more about to learn more about his work and background.

Hitoshi will be recognized at this year's Liferay Japan launch event next month!

 

Alexey Kakunin

Alexey has been active in the community for quite some time and has done a lot of work contributing and maintaining the Liferay/Activiti integration, providing an open source choice when using workflow with Liferay. In addition, he has been very generous with code contributions (bugfixes and improvements) to Liferay Portal, over half the time providing fixes along with his bug reports. It's quite natural for him to give back to the community, and I encourage all of us to take Alexey's lead!

 

David Nebinger

David stumbled upon Liferay in 2006 while looking for an open source portal platform for an intranet, and over the last year, really stepped up his game in contributing a huge body of knowledge to our forums and community documentation. He has a solid understanding of Liferay internals and openly provides his unbiased opinions and stories from his Liferay experience. David was also a featured speaker at this year's North America Symposium and was awarded with a quarterly contributor award earlier this year.

 

Juan Gonzalez

Juan embodies the spirit of openness that any community desires. He's been quite busy this year on the forums, but has also contributed lots of code in the form of bug fixes, improvements, new features (Assisting in the implementation of things like Video/Audio preview), and most recently providing easy to use patch sets for Liferay Portal CE. Juan is also active in the Community Security Team, and helps to champion Liferay in his work in Spain and elsewhere.

 

We have all benefited from the work of these four individuals, but there are many others who make our community one of the most active and positive groups to ever be associated with! I sincerely wish to thank all of you for making it so!

Partner Contribution of the Year

JavaServer Faces is one of the most widely adopted and powerful user interface framework for web applications. This didn't happen by accident, as developers have chosen it for its powerful features and easy integration with web technologies like Liferay. portletfaces.org was established by Mimacom AG and Triton Services to meet the need for an open community built around the related standards JavaEE, JSF, and Portlets.

With the popularity of Liferay and its beneficial association with the JSF community, it was a win-win decision to contribute the projects under portletfaces.org to the Liferay community, and both Mimacom and Triton Services were awarded Partner Contribution of the Year awards for this act.  Neil Griffin has a great writeup of the projects, and you can also read the press release for more information.

Mimacom

Triton Services

 

Liferay Community Excellence

Our strong worldwide partner network continued to move Liferay technology forward this past year, providing world-class Liferay services and contributions to our growing community. Last year we recognized the top 5, but this year the number jumps to 7 - due to the quality of work and outstanding level of community contribution!

Acando

Acando is very active in Norway and elsewhere in Europe, and has single-handedly provided 97% of the Norwegian translations for Liferay technology. They are also a founding member of the Norway User Group and regularly organize events for the group and for the larger Liferay community. This is the first of hopefully many years of community excellence!

Acando had planned to attend the Europe Symposium to receive their award - but unfortunately (or fortunately!) they had a last minute business opportunity, so we'll see them next year!

 

B2B2000

As a Platinum sponsor of this year's Liferay Spain Symposium, B2B 2000 is no stranger to the community. They had a well-rounded contribution effort this year, providing over 4000 individual Basque translations, are very active in #LSUG (the Liferay Spain User Group), and are very helpful on our forums (not only in Spanish!).

 

Cignex Datamatics

Cignex Datamatics is a repeat winner this year, and have contributed to virtually every facet of our community, including very helpful forum activity, knowledge sharing via their many online Liferay webinars, and are also contributing in our community programs such as BugSquad and others. Several of Cignex' ranks have also been recognized individually this year, and are very passionate about Liferay, both online on liferay.com, and in person at industry events such as the recent North America Symposium.

 

Componence

Based in the Netherlands, but making their presence known throughout our worldwide community, Componence has continued its tradition of open source contribution for Liferay. They founded and continue to push the Netherlands User Group forward, contributed time and energy to execute the Liferay Community Survey, provided translations, and participate in community efforts like BugSquad, Community Verifier, and are a regular presence at the Europe Symposium (where they organized a Table Football tournament for the community!).

 

Permeance

Hailing from Australia, Permeance has been very active in our forward-looking programs, providing feedback in the Liferay Portal 6.1 BugSquad Feature Reviews late last year, and are very active in promoting Liferay in the region. Permeance also dedicates a large percentage of their time to our community, recognizing the essentially free training one gets by participation.  Their work on our issues database and forums has helped make our recent releases better for them, their clients, and our community as a whole.

 

Savoir-faire Linux

Another repeat winner, Savoir-faire Linux is committed to open source, clearly understanding the benefits of participation and contribution. They have contributed major features in the past (enjoying Faceted Search? Thank these guys!), and this year were also active on our forums, contributed to BugSquad, sponsored the North American Symposium, and provided over 2500 French translations of Liferay.

 

SMC

Finally, SMC is also a first-timer (but were in the top 10 last year!). SMC founded and continues to lead the Italy User Group, and was one of the first Liferay partners ever, so it is no surprise they are committed to our community. SMC also contributed to our Italian and English forums, and is the organizing sponsor of this year's Italy Symposium next month.

 

Final Thoughts

In closing, I'd like to sincerely thank all of the above community members, and everyone else in the community who choose to use Liferay, choose to help make it better, and choose to brighten everyone else's day a little bit each time they do.

Community Meetup at the North America Symposium

Staff Blogs 26 settembre 2012 Da James Falkner Staff

If you are attending this year's Liferay North America Symposium in two weeks in San Francisco, on Sunday evening (the evening before the event begins) Liferay is hosting a community meetup. This will be a free event, starting around 8pm, at Irish Times [Map and Directions]. This is very close to the symposium venue, about a 3 minute walk.  Come meet your fellow community members, Liferay staff, and other interested parties with some free drinks, snacks, and interesting conversation! It'll be a great way to start off your two-day symposium. If you are interested in attending, let me know by leaving a comment on this blog post, so that we can gauge how many will be there! See you in San Francisco!

2012 Liferay Community Survey

Staff Blogs 25 settembre 2012 Da James Falkner Staff

Hey all!  As your community manager, I am always trying to learn from you as much as possible, in order to make our community a better place to share ideas, meet new people, and generally grow the world of Liferay.  However, for such a large and active community, I alone cannot ever hope to conquer this task, so your Community Leadership Team has been exploring ways to solicit feedback, and not just ordinary feedback, but feedback that gets to the root motivations of participation (or not!). To that end, today we are opening the 2012 Liferay Community Survey - please take a few minutes (ok, about 10 of them) and share your feedback with us.  The results will help us further understand what motivates your participation, the improvements you wish to see, and how we can better attract and retain new community members in 2013 and beyond!

The survey will be open until October 23.  Your answers are completely anonymous, unless you wish to receive feedback, or more importantly have a chance to win cool prizes offered by our survey sponsors: MyOffice24x7, Componence, and Liferay!  Gift cards, Liferay books, and other fabulous prizes will be awarded to a few lucky survey respondants, so take the time to take the survey and make your voice heard!  Once the survey closes, the community leadership team will review the findings and present them to the community, and the results will be used to tune our efforts in the community and project going forward.

By the way: the survey questions were generated from the community, and the survey itself is implemented using MyOffice24x7 SmartForms, running on Liferay 6.1 CE GA2, configured by Componence.  So it truly was a Liferay Community effort, and we are happily "eating our own dogfood", thanks ya'll!

Community Roundup

Staff Blogs 22 agosto 2012 Da James Falkner Staff

Guess what?  It's time for another Community Roundup!  I know it's been a while since the last roundup.  It's been quite a busy last few months in the Liferay Community.  We saw the release of several Liferay product updates, the soft opening of the Liferay Marketplace, and several new initiatives in the community.  I'll try to cover as much as I can, filtering only the best for you, with lots of links to keep you informed and up to date.  On with the show!

  • The fall event season is heating up.  I don't get out much, so it's nice to be able to connect an online identity to a real person every once in a while.  Liferay is active in community meetups and industry events -- you may have seen us at this year's OSCON, and read below for details on local community meetups happening around the world.  Many events are free to attend (like our community meetups), so don't hesitate to come say hi if you can! We will also be at Gartner's PCC in London, the Jenkins User Conference in San Francisco, JavaOne (also in SF), the AFCEA Fort Knox Industry Day, and then the entire month of October (and some of November) you'll find 4 Liferay Symposiums in a row - San Francisco, Frankfurt, Madrid, and Milan.
  • Speaking of symposiums, last year we began to accept topic submissions from our community.  Last year, at the US symposiums, I believe we got around 5 submissions.  This year, it was close to 30.  I'm guessing the European symposiums are seeing a similar increase!  I was shocked and awed at this.  And they weren't run of the mill sales pitches, these were real technology and community discussions, which I'm sure made it tough on the organizers to choose.  You can see the program listings: [North America, Europe, Spain] and I highly encourage you to attend at least one.  The Spain and Europe CFPs are still open, so be sure to submit if you've got a topic you wish to present.
  • The much anticiated opening of the Liferay Marketplace finally arrived in late July.  The Liferay Marketplace is the new place for our community to share, browse, and download Liferay-compatible apps.  You can find all of Liferay's supported plugins, and in the near future you will be able to upload your own applications, and make them available on the Marketplace.  Next week (August 27-31), Liferay will host several live sessions in multiple languages and timezones to discuss how you can use the Marketplace and what you can do with it today, and what's coming up.  I highly recommend you attend at least one!
  • Also on the release front, we saw the release of Liferay Social Office 2.0 CE.  A much needed refresh of the Social Office product, this new release has too many new features to go over here.  It looks really great, so give it a go!
  • July also saw the release of Liferay Portal 6.1 CE GA2 and EE GA2.  This update brought several important updates to the platform, including support for the aforementioned Marketplace, and important security updates.
  • Security is very important to anyone who uses Liferay, and the newly-formed Community Security Team has taken on the task to educate developers on security, and help to find, fix, and notify the community about security issues in Liferay.  If you are interested in learning more or joining this effort, contact the team today!
  • As you know, last year we began the Community Verifier team, to help verify existing issues in Liferay, and clean up our JIRA database of backlogged issues.  The team has donated a huge amount of their time, and has verified/triaged over 370 issues since January.  Well done!
  • Juan Gonzalez (aka juangon) is a very active in our community and is always willing to contribute, whether it's on the forums, the Community Security Team, or even on other open source projects.  Most recently, he collaborated with the fine folks on the XMLPortletFactory to integrate it with Liferay's built-in workflow engine.  Check out Liferay XMLPortletFactory Workflows!
  • Participation in our community is one of the best ways to get to know the technology.  Contributions, no matter how small, should be treated as a gift to the community, and we have not done a great job to date of shepharding those contributions into the project.  In an effort to improve this, Drew Blessing has kicked off a new effort in the Community Verifier program to pair up contributors, community verifiers, and Liferay core engineers, and get those contributions flowing once again.  But we need your help!  If interested in joining the CV program, please join this thread and get involved!
  • Shout-out to our 2012 Q2 Top Contributors: Jelmer, Tejas, and Amit have been kicking butt in their own special ways in our community, and I want to personally thank them for their efforts.  Of course everyone who contributes should be commended, and so I look forward to Q3 and beyond.
  • Olaf continues to provide visibility into our community, through his regular podcast.  Most recently, Radio Liferay has featured Jim Hinkey on Javadocs, Bruno Farache (aka Bruno Admin), Juan Fernández (Core Engineer and active Community guy), Michael Young (One of Liferay's Founders), Jeffrey Handa (Training), Greg Amerson (of IDE fame), and a host of others.
  • More Liferay User Groups are popping up!  We welcome new groups in Denver (US), New York/New Jersey (US), Dortmund (DE), and Twin Cities (US).
  • User Group activity is picking up across the world.  India held their first and second meetups in Pune and Ahmedabad, and plans for Bangalore later this year.  The UK is lighting up as well, with meetups planned for September.  Spain, Netherlands, Dortmund, Austin, Denver, Twin Cities, and Belgium also have (or recently had) events - check their pages for details, and get to know your local Liferay community!
  • CMSWire recently held a discussion: "Does Open Source Encourage and Support Innovation?".  This is of course very important to understand when considering Open Source for your business.  We in the community of course believe in it, but it's nice to see an external perspective.  Of course, the only vendors consulted were open source, but the arguments made are sound in this blogger's opinion!
  • Our Liferay Community is but one of many in the software industry.  Roland (from Nuxeo) recently talked with community managers from several open source communities (including ours!), and wrote a nice 4-part piece on the practice of community management. [Part 1, Part 2, Part 3, Part 4].
  • Our fearless community champion Ray continues his adventure.  Who is this mysterious hero that keeps saving Ray?
  • There are new, custom designed Liferay teeshirts available at cost (no markup) at Liferay's CafePress online store.  These were designed by our very own Bryan Ho!  Women's and Men's sizes and fits available.  You can even get a onesie for your little one.  Also, I heard a rumor of a 3rd design that was never published and is really hard to find - if you find it, let me know.
  • Earlier this year, the community began accepting new Liferay Community Projects - since then several have popped up, the latest of which is a handy JavaScript utility belt for Liferay Developers: Rogers.js.
  • Thanks to YOU, our Liferay Community, we have been voted #1 for SourceForge.net's July Project Of The Month!  Check out the interview with Brian Chan, one of the Liferay founders, who was instrumental in us finding and continuing to use SourceForge as the home for Liferay downloads back in the stone ages of Liferay.  I was very happy to see so many of you lend your voice.  We beat SugarCRM!  And I now have 94 new and useless Twitter accounts.  Just kidding.
  • Wasim continues to contribute some great work in the area of user experience in his blog.  Liferay 6.1 Theme Initializer 2? Yes, please!
  • Random tweet: @simonfeesh Totally geeking out today. Am absolutely impressed with @liferay. Wow. Makes other CMS platforms look ordinary.
  • Mobile is still in its infancy.  There's too much confusion, I can't get no relief.  One of the tenants of Liferay's design is that it gives you the choice about how to do many things, including mobile support.  Two articles stuck out recently: Milen describes how to use the Mobile Device Detection in Liferay 6.1.  And Tony Byrne from Real Story Group explains the choices one must make when designing for Mobile using Liferay. Both nice articles (be sure to read Nate's comment on Tony's article!).
  • Jignesh has very useful tidbits of Liferay Developer goodness.  I particularly like the coverage of AlloyUI and Liferay's WCM.
  • Jelmer gives us some nice tips / best practices for Liferay development.  If your Liferay project involves continuous deployment of Liferay and your plugins, there are some nice tips here.
  • Liferay held a Twitter contest back in May - you can read more about it on the results page, but what I was particularly happy about was that the prizes chosen were characterized as "Cool and baffling" :)
  • FancyBox Portlet anyone?  Davide brings us this interesting visualization tool for Liferay (using jQuery).
  • As you know, earlier this year the PortletFaces project was moved under the Liferay Community umbrella, headed up by Neil Griffin.  The Liferay Faces project has just had their first GA release of Liferay Faces, welcome news for JSF+Liferay users.  Also, check out the nice demos page if you're wondering what Liferay Faces can do for you!
  • The Liferay IRC channel (#liferay on FreeNode) has been picking up steam - we're up to around 30 people at peak times (generally Monday morning for some reason) and maybe 15 or so 'regulars'.  Come join us!  I wonder if we should start up bi-weekly meetups!  For Hungarian users, we now have a #liferay-hu channel as well!
  • Liferay IDE 1.6 has recently been released, with awesome new features for developers like automatic source attachment for handy debugging, new support for JSF Projects, ServiceBuilder enhancements, and other community contributions. Nice job Greg and team!
  • Tejas (one of our most active contributors recently) also maintains his own blog - most recently discussing the creation of Portlet URLs from Theme template code.  Thanks Tejas!
  • Dave Nebinger shows how you can integrate Piwik (open source analytics) with Liferay.  I came across Piwik back in my Community Equity days, and it is a really nice solution for tracking visitors and gathering nice looking data. Thank Dave!
  • Speaking of monitoring things, what about monitoring Liferay itself?  Mika has a nice article on using Nagios, Jolokia, and JMX4Perl, complete with fully functional configuration examples.
  • New Blog Entries: Cincinatti Film Festival and Liferay, Custom Footer Navigation, Maven and GA2, 6.1 Development Guide, Liferay Open Development, Workflow Context Variables, and many more.  Also, I know I've promised this for a while now, but we are making progress on opening up liferay.com blogs for the entire community.  Stay tuned!
  • New Wiki Updates: Community Verifier Contributors, Using Custom Fields, User Feedback, Contributing using Git and Github, Getting Started as a Developer, and many more.
That's all I have for you today, folks.  Thanks again to our amazing community that keeps giving and keeps me going.  Until next time!
 

Social Office 2.0 CE Release

Staff Blogs 1 agosto 2012 Da James Falkner Staff

Today Liferay released the next CE release of its flagship social collaboration product: Social Office 2.0 CE! [Download from the Liferay Marketplace] [Documentation]

Liferay Social Office is a social collaboration solution for the enterprise that streamlines communication, saves time, builds group cohesion and raises productivity. It is built on Liferay Portal, and shares much of its functionality, but also adds additional functionality for social networking and department-level collaboration.

The Social Office team, in conjunction with its awesome community of users and developers, have spent many months getting this release ready, and I'd like to describe some of the details about new features and additions to the product.

Downloads

Social Office 2.0 CE is now available in the newly opened Liferay Marketplace.  It can be easily added onto your existing Liferay Portal installation (starting with Liferay Portal 6.1 CE GA2).  Simply navigate to Control Panel, click on the Store tab (under the Marketplace section of Control Panel), and you will see Social Office 2.0 as a Featured App.  Alternatively, you can download it through the Marketplace's web store at liferay.com/marketplace.

New and Improved Features

Social Office 2.0 is a major revamp, and includes many features for social collaboration.  Here are a few of the highlights, but I highly recommend you check it out for yourself!

Installation

Unlike previous versions of Social Office, Social Office 2.0 is available as an application that can be installed on Liferay Portal 6.1. Liferay applications, or apps, are packages of Liferay plugins that are grouped together with descriptions, version information, and other metadata. Social Office 2.0 is one of those applications. They're available from Liferay Marketplace. Prior to version 2.0, Social Office was provided as an independent product that was based on, but separate from, Liferay Portal.  Read the Social Office Documentation for more details on getting started with Social Office 2.0.

Dockbar Integration

Social Office fully integrates with Liferay's Dockbar, providing easy to access links to common functions and a notification area to quickly see what's important to you.  Users are alerted to new notifications or requests, providing a quick means of responding to the notification.  

Profile

Your profile page represents you to other users.  It provides details about you, including your name and picture, descriptions that you provide, links to your presence on SO and other social sites, status updates, site memberships, a summary of connections, and other pertinent personal information about you.  it has had a major revamp in 2.0.

Dashboard

Your dashboard shows you a collection of information pertinent to you, such as upcoming tasks and events, your status updates (and the ability to enter new ones), related activities, and allows you to manage your contacts and private messages. The Dashboard is easily reachable from the Dockbar.

Contacts Center

New to Social Office 2.0, the Contacts Center is a key enhancement that makes finding, following, and tracking your contacts much easier.  You can add other contacts as connections or simply follow them, to receive updates when activities occur.  You can also do things like send private messages, or even block them.

Events Center

The Events Center integrates with Liferay's out-of-the-box Calendar functionality, giving you a birds-eye view of upcoming events that you are involved with.  

Followers and Connections

You can now connect to other users as a two-way relationship (friending), or simply follow users to receive updates on their activities through the newly revamped Activities Stream.

Activity Stream

Social Office 2.0's new Activity Stream integrates with all facets of Social Office, showing you activities from your contacts and followers.  You can also filter activities to only display those from connections, those you are following, activities on sites you are a member of, or your own activities.

Microblogging

Another key feature and highly requested improvement is the ability to publish content to your very own microblog, targeting subsets of your contacts, or broadcast to the entire site.  

Hashtags, Mentions, and Autocompletion

When sending messages or updating your status, you can use #hashtags to give context to your post, and you can @Mention other users, providing an easy link to their profile and giving them notice that you are talking about (or to!) them.  When using mentions, Social Office dynamically provides autocompletion for contact names, so you can quickly find the person you want to mention.

Private Messaging

Another highly requested feature, Social Office allows users to send Private Messages (PMs) to other users.  Messages are email-like and you can also attach content to the message, and include multiple people in a private conversation.

Notifications

When on a Social Office site, your notifications are displayed in the Dockbar, giving you quick access to important information or activity to which you need to respond. Clicking on the Notifications dialog shows you all of your unread or pending notifications, and can be cleared as needed.

Site Management

Social Office adds extra collaborative tools to Liferay and allows you to quickly set up sites designed to facilitate collaboration. Each site is template-based and designed to provide a single group or team with a virtual shared workspace. Members of your organization who belong to multiple groups or teams in your organization can belong to multiple Social Office sites on the portal.

Tasks Management

Social Office also features a Task Management System, allowing you and your team to track tasks to completion.  Tasks can be filtered by tag or site, and expected task attributes like due date, assignee, percent completed, are present.

Fluid Layout

Social Office features a new flexible theme. You can toggle between a fixed and fluid theme layout where fluid layouts conform to fit the width of the screen, giving you extra real estate to manage your site.

Integration with Liferay Portal

Build on the award-winning Liferay Portal, Social Office users and sites can also use Liferay's built-in document management, blog, wiki, forum, chat, and custom plugins typically used with Liferay.
 

Integration with Liferay Sync

Liferay Sync transforms the Liferay platform into a central, easy-to-use document sharing service.  Combining Sync + Social Office allows your teams to access Social Office documents from desktop and mobile platforms.  The Community Edition of Sync is limited to one Social Office site.  If you need to sync multiple sites, get the Enterprise Edition.
 

Documentation

The Liferay Documentation Team has been hard at work updating all of the documentation for the new release, and the new "Working Smarter With Social Office" is ready!

Bug Reporting

As always, the project continues to use the Social Office JIRA site to report and manage bug and improvement tickets. If you believe you have encountered a bug in the new release (shocking, I know), please be cognizant of the bug reporting standards and report your issue on issues.liferay.com, selecting the SOS project and the "2.0.0" release as the value for the "Affects Version/s" field.

Getting Support

Support for Social Office 2.0 CE comes from the wonderful and active community, from which Liferay itself was nurtured into the enterprise offering it is today. Please visit the community pages to find out more about the myriad avenues through which you can get your questions answered. For Enterprise customers, Liferay also offers Social Office 2.0 EE, which is due to be released shortly after this CE release.

What's Next?

Of course we in the Liferay Community are interested in your take on the new features and improvements in Social Office 2.0.  If you are interested in learning more about how you can get involved, visit the Liferay Community pages and dig in.  Also, check out the Social Office Project page for even more SO-specific information.

Liferay Portal 6.1 CE GA2 Release

Staff Blogs 1 agosto 2012 Da James Falkner Staff

It's finally here - Liferay Portal 6.1 GA2! [Download] [Quick Start] [Documentation]

This is an update release for Liferay Portal, bringing a host of fixes and some improvements based on feedback from the community.  

Release Nomenclature

Following Liferay's versioning scheme established in 2010, this release is called Liferay Portal 6.1 CE GA2. The internal version number is 6.1.1 (i.e. the first update release of 6.1). Future CE releases of 6.1 (if any) will be designated GA3, GA4, .. and so on. See below for upgrade instructions from previous releases.

Downloads

You can find the GA2 release on the usual downloads page. If you need additional files (for example, the source code, or dependency libraries), visit the additional files page.

Changelog

In addition to the numerous bugs that have been fixed since 6.1 GA1, Several new improvements have gone into this release. Highlights include:

Documentation

As always, the Liferay Documentation Team has been hard at work updating all of the documentation for the new release. This includes updated javadoc and related reference documentation, and updates to the User Guide and Development Guide. You may have been watching the progress of it via its new home on github, but if not, you can access the full documentation on the documentation page.

Bug Reporting

As always, the project continues to use issues.liferay.com to report and manage bug and improvement tickets. If you believe you have encountered a bug in the new release (shocking, I know), please be cognizant of the bug reporting standards and report your issue on issues.liferay.com, selecting the 6.1.1 CE GA2 release as the value for the "Affects Version/s" field.

Upgrading

As a general rule, you can upgrade from one release of Liferay to the next. This means that you can upgrade from 5.2 to 6.0, or 6.0 to 6.1, but not directly from 5.2 to 6.1. For 5.2 to 6.1, you would need to progress from 5.2 to 6.0, then 6.0 to 6.1. See the Upgrading Liferay chapter of the Liferay User Guide for more detail on upgrading to 6.1.

For users of GA1, you can directly upgrade to GA2 following normal upgrade procedures found in the documentation.

Getting Support

Support for Liferay 6.1 CE comes from the wonderful and active community, from which Liferay itself was nurtured into the enterprise offering it is today. Please visit the community pages to find out more about the myriad avenues through which you can get your questions answered. Liferay and its worldwide partner network also provides services, support, training, and consulting around its flagship enterprise offering, Liferay Portal 6.1 EE, an update of which is due to be released shortly after this CE update.

What's Next?

Of course we in the Liferay Community are interested in your take on this update. Work has already begun on the next evolution of Liferay. If you are interested in learning more about how you can get involved, visit the Liferay Community pages and dig in.

Liferay Community Security Team

Staff Blogs 9 luglio 2012 Da James Falkner Staff

I'm particularly happy to announce that today we are launching a new initiative in the community around Liferay security.  From the new Community Security Team (CST) pages: "The Liferay Community Security Team is an all-volunteer group of community members who manage security issues related to Liferay CE. When security-related issues arise in the open source Liferay project, the CST works to minimize the impact and provide notification and relief to the community. In addition, the CST provides ongoing education to developers and users to keep their Liferay sites secure."

This team provides a much needed and long overdue element in the Liferay open source community, helping to quickly fix security issues and provide patches for existing community users.  As Liferay (and many other open source projects) continues to grow in usage and popularity, so too does the importance and potential impact of security issues, and it's vital that we respond quickly with a well understood and predictable response. In addition to reacting (through advisories, patches, etc), this team is also chartered with being proactive in the community, educating developers, administrators, and end users about security best practices and specific techniques that can be used with Liferay.

The CST pages contain a wealth of information including:

  • How you can get involved in the team
  • How the team operates
  • How to subscribe to receive new security advisories
  • How to respond to such advisories
  • How to report new issues
  • How to install patches
  • and much more

As an important part of and corporate sponsor of open source, Liferay is also issuing a corporate security statement, outlining its commitment to security, and policies around reporting to the wider community.

Getting Involved

The initial CST comprises of individuals from the wider Liferay community, as well as employees of Liferay, Inc. All community members are welcome to participate! Because membership gives access to information about potentially sensitive security issues, membership is somewhat limited to those in the Liferay community with a proven track record in the areas related to security or with special skills needed by the team. The best way to get involved is to review security fixes with a security mindset, get down and dirty and find and/or fix a few issues, and interact with the team in its course of duties.

The team is currently busy catching up with a number of security issues that were reported in the Liferay Portal 6.1 CE GA1 release.  Several fixes are currently available through the CST, and a couple more are expected in the next week (be sure to subscribe to the Security Advisory Forum or the feed (click on the RSS/Atom icon on the Known Vulnerabilities page)

What's Next?

As with any new venture, there are still a few unfinished items and there are bound to be hiccups or things we can improve on, so please be patient and constructive with any feedback you wish to give.

The team is still in the process of ironing out its processes, and some work remains for GA1 (as stated above).  We are also expecting a GA2 release of Liferay Portal 6.1 soon, and at that point the team will shift to managing that release's security.  Once the processes have been battle-tested, the team will begin to execute on other areas of its charter (e.g. education and outreach).  The team will also begin to integrate its output within other areas of the community (e.g. pointers to latest patches on the main CE download page, or perhaps notifications during initial install that there are new fixes available).  The team will also provide translations for the CST page content and advisories in the following weeks.

There are a lot of community members that care about security, I am hopeful that together we can ensure continued confidence in the security of Liferay!

Liferay North American Symposium 2012

Staff Blogs 14 giugno 2012 Da James Falkner Staff

This year, the Liferay Community will gather around the world to learn, share knowledge, and meet fellow Liferay technologists and experts, as part of the popular Liferay Symposium series.  The Liferay North American Symposium [Register] takes place October 8-9 in San Francisco, and it will be one you DO NOT want to miss.

What's new this year?

You mean besides everything?  It's our first time in San Francisco ("Helloooo, Frisco!!"), one of the most beautiful and interesting cities in the world (in this blogger's humble and biased opinion).  We've got an awesome line up of speakers, including Liferay leadership, industry luminaries, and real world customers sharing case studies.  There are many more workshops and training activities than years past.  There's a mobile app with cool features.  My jokes are AT LEAST 30% better.  And many more surprises lurking for attendees.

Why should I attend?

Besides the normal (but still awesome) presentations about Liferay technology, case studies, etc, we also have many workshops that attendees can attend, to get hands-on experience with Liferay and related technologies.  For those who want even more depth, the full-on Liferay training will be held the day after the symposium.  There is also a LOT to do in San Francisco and the SF Bay Area, before, during, and after the symposium.  But most important (again, in my humble and biased opinion) is that you will meet and engage with the lifeblood of Liferay's community -- its people.

These are the people that make the Liferay Community clock tick -- our open source developers and contributors, partners, customers, ISVs, Marketplace publishers, and everyone in between.  It is simply the best place to get the complete Liferay experience in an action-packed 2 day event.  Registration is now open, and I'm telling you -- you won't want to miss this one.

Getting Involved

Just like last year, the agenda will include topics submitted by YOU, the Liferay community! Join the largest gathering of the Liferay community and participate in the sharing of knowledge and expertise with fellow community and Liferay experts.  Submit your topic for consideration, and join us in San Francisco, Frankfurt, Madrid, and (somewhere in) Italy!  Speakers will be announced August 15 for San Francisco, so don't wait!

Demystifying Liferay's Open Development

Staff Blogs 13 giugno 2012 Da James Falkner Staff

"What is Liferay working on?"

This question is probably the most popular high-level question asked by the our community.  Whether you are an enthusiast, open source Liferay developer, partner, or potential or long-time customer, you want to know what's coming up and what's being worked on.  On my first day on the job, in my first blog post as your community manager, I promised to "Engage with you on the roadmap for 6.1 and beyond".  Today marks a significant step towards closing the gap between what you think the Liferay Community is doing and what we are actually doing.  This information has sort of been there all along, in the form of individual tickets in JIRA, but our process is evolving and becoming even more transparent and easier to understand. 

A Brief History of Liferay's Development Process

In the early days, when the community was very small, pretty much everyone was in tune with what the community leaders were doing.  There were twice-yearly meetups in LA, the source code base was small, and there wasn't a ton of people issuing requests and complaints and suggestions for improvements.

As the popularity and user base of Liferay grew, and as companies started using it more and more for mission critical applications, the need for knowing what was being worked on (and therefore what could be expected in the next release) grew proportionally.  Since Liferay (and liferay.com) was already a social collaboration tool, and had amazing features like a Wiki, The Roadmap was enshrined as a wiki page (here's the one for 5.0) for all to see and collaborate on, with the expectation that it would be nurtured and updated frequently.

Unfortunately, the wiki turned out to be the place where the roadmap went to die a quiet, ignominious death.  The problem was not that wikis are inherently bad, it's just not the right tool for a quickly evolving project with lots and lots of details.  No one was willing to babysit the wiki page and ensure its accuracy on a daily basis during product release cycles, because it was not much more than an electronic whiteboard (and not very powerful or fun to use).   So, we were left with an afterimage of what the project was supposed to be at the beginning of the release cycle.

In the meantime, Liferay Program Management was becoming more adept at using JIRA to its fullest potential, to manage the huge activity occurring on issues.liferay.com.  What was once essentially a large, flat list of bugs and improvements (with the same workflows and same metadata - name, description, assignee, etc) was slowly transforming into a powerful issue management system with customized metadata, workflows, new filters, and OpenSocial visualizations built on top of the "flat list of bugs", giving the community never-before-seen ways of visualizing and managing issues.

In addition, Liferay itself was changing - trying out new development models and seeing which ones best fit the company's and community's development style.  We're not pioneers here - effective development teams have been using various models like XP, Scrum, Kanban, etc for years, so we were just picking those that seemed to match our development culture best, modifying as needed, and marching on.  In October 2011 I visited our Madrid office, and was pleasantly surprised to see the whiteboard in the office look something like this:

( Attribution   Some rights reserved  by  Plutor)

I was like "ahhh.. low tech solutions for low tech problems.  Genius!".  If I could set up a camera in this office, and take a picture every hour and upload it to liferay.com, then we'd all have a pretty clear idea of what was currently being worked on and we'd have a constantly updating picture of what Liferay thought should be in the next release.  But a camera is too fragile, and we can't all be in Spain (though that would be nice...).  What they were practicing was a form of Kanban, prototyping it with the development team there.  We have now taken it from pushpins and post-it notes to JIRA and one of its many plugins called "Greenhopper".

This post isn't meant to educate you on what Kanban is or how to use Greenhopper.   Instead, I'll explain how it can be used to visualize the work of the Liferay developer community (Side note: I tend to lump Liferay employees with the rest of the community!).

The Liferay Activity Board

Many product presentations end with a Roadmap Slide - this is the slide where high level features are paired with expected due dates, and is usually accompanied by some kind of disclaimer which absolves the presenter of all responsibility for the dates and content presented.

This is not a roadmap.

Rather, what we now have at our fingertips is a view onto what was formerly a post-it note board maintained in Liferay's development centers. It's better and more useful than a static roadmap.  At this point you may be asking yourself "So what, I don't want to see the 50 bugs that were fixed today, and I don't care that Ryan was blocked on LPS-23133 and Julio's average cycle time is 7.5 days.  I want to know what's coming in the next version of Liferay!"  Fair enough.  The nice thing about how we are using JIRA and Greenhopper is that it is now possible to get exactly that - a view onto the current, major, high-level themes being worked on for the next version of Liferay, ignoring all of the boring details.  With the new Community Rapid Board, you can do exactly that:

It's called a Rapid Board and is essentially a 2D table showing Stories flowing through various states.  A Story is a supporting artifact for a set of requirements.  The labeled rows (Quick Wins, Collaboration Calendar, etc, also called Swimlanes) represent groups of related stories under the same feature area that are currently being worked.  Columns represent current state of the stories being worked.  So, for example, for Liferay 6.2, you can see that the following high level items are planned or being worked on:

Of course, the set of visible feature areas for 6.2 is evolving, so this list will change over time.  You can click on individual stories and drill down to your heart's content.  Eventually you'll arrive at one or more JIRA tickets representing the lowest level of development subtasks assigned to individual developers, which can ultimately be mapped to source code changes at github.  Following this rabbit hole is very instructive and helpful in the future when unraveling issues :)

Quick Wins

Quick Wins allow any Liferay Developer to work on whatever they want under certain conditions.  Often times, community contributions that you make are handled as Quick Wins.  These are shortcuts to the development process - things that can typically be handled generally within one day, without undue process.  Liferay has always benefited from these and we want to encourage them to keep happening.

How is this different?

Liferay is not only an open source product, its development process is also very open, and now we are making it even easier to keep track of what's going on, which helps you get involved earlier and provide feedback on how you want to see the product evolve.

Of course, it's just as easy to neglect a fancy tool like JIRA as it is to neglect a wiki, so how is this any better?  The difference is that this tool is now in the critical path for daily (and sometimes) hourly work of our community of developers.  Neglect on anyone's part will cause pain for many other people, so it's in everyone's best interest to keep things accurate and use the tool for its intended purpose.  Not only that, it's easy and fun to use (it can be very therapeutic to weed through a complex board every day and see the progress of tickets).  And in the end, it provides a rich set of tools to measure progress and find roadblocks and places where development process can improve.  Of course, there is a higher learning curve compared to a wiki page, but in the end it is worth it.

What does this mean for me?

Right now, these JIRA-based tools are used internally by Liferay's development teams.  Outside of these teams, the process for the community remains the same (for now) - file bugs at issues.liferay.com, discuss new features and improvements via the forums and Proposals Wiki, and then file new feature requests via issues.liferay.com.  These will in time be promoted to  Stories (often times Quick Wins).  As a separate effort, your Community Leadership Team and Liferay Product Management teams are  working on improving the "ideation" experience within our community, to make it very easy to crowd-source new ideas and promote community-born ideas into reality much faster, but that's a separate blog post in the near future (I promise!).

I am sure that "Roadmap Slides" won't be going away anytime soon - you'll probably see several of them in the upcoming Liferay Symposiums - but the extra granularity and daily (and sometimes hourly) reflection of the current state of Liferay within these Rapid Board views gives everyone a realtime view onto the what is happening with Liferay development.

Twitter Contest Results

Staff Blogs 31 maggio 2012 Da James Falkner Staff

The results are in!

Liferay launched its first Twitter contest earlier this month with this tweet. Our guest judge for the two-week long contest was journalist Josette Rigsby from CMS Wire.  Josette has carefully looked over each entry, and has provided her expert judgement as follows:


Liferay has managed to combine two of my life long loves - super heroes and code. So when they asked me to judge a contest of developer super powers, I couldn't resist. Almost everyone that has cracked open an editor and created a program has wished for the power to slay issues (and occasionally users). Apparently, some of you wish for a lot more. There were lots of good entries, but many revolved around a few key themes:

  • Coding Better: 38%
  • Coding Faster: 11%
  • Coding Longer: 7%
  • Coding More Enjoyably: 30%
  • Taking Revenge on Frustrating Problems: 14%

Let's take a look at the entries that stood out the most. In third place is @mariogrimaldi89 for his desire to have the ability to read the client's mind to really understand what he wants [tweet]. We are right there with you, sir. We all know testing is important, and curse not having them when we have to work on somebody else's code. However, the love for testing sometimes briefly disappears when we're the ones writing the code. So, second place goes to @LeoPratlong for his desire to be able to write all tests at once: unit, functional and UI from user stories [tweet]. Last, but certainly not least, first place goes to @ben3342 for his wish to code with his mind, or if that doesn't work out, his beard [tweet]. Congratulations to all the winners and thanks to everyone else for taking time to enter.


So, there you have it.  Winners will be notified via email to arrange delivery of their cool yet baffling prizes, as described below.  Be sure to follow @Liferay for future Twitter contests, and keep rooting for Ray, my favorite superhero!

Prizes

Ben, Leo, and Mario will each get one of the 3 fabulous prizes!

Col. Fezziwig's Eccid Blaster Steampunk Ray Gun

This Eccid Blaster replica ray gun hearkens back to the days of Jules Verne and H.G. Wells. Like something out of a Tom Swift novel, the Blaster features incredible detail, hand-painted accents and has a removable "laser" cartridge on top.

Sphero!

The Sphero is simply a robotic ball that rolls around on the floor and is controlled through a virtual joystiq on your smartphone. After you’re finished being easily amused with your control over a plastic ball, download the free apps and have some more fun playing Sphero-integrated games such as a side-scrolling space game and even golf.

Arduino Uno Starter Kit

The Arduino Uno is a microcontroller board based on the ATmega328 (datasheet). It has 14 digital input/output pins (of which 6 can be used as PWM outputs), 6 analog inputs, a 16 MHz crystal oscillator, a USB connection, a power jack, an ICSP header, and a reset button.  Pefect for the tinkerer in you!

Twitter Contest: Web Developer Superpowers

Staff Blogs 6 maggio 2012 Da James Falkner Staff

Web developers are often faced with a daunting task: make a compelling web experience as quickly as possible for as little cost as possible.  With the vast array of resources at their disposal thanks to the internet, you'd think this task would be easy, but soon reality sets in, and developers are left wishing they were able to do things outside the capabilities of mere mortals.  So, the question becomes:

If a web developer could have a superpower, what would it be?

You tell us.

Liferay launched its first Twitter contest today with this tweet. Our guest judge for the two-week long contest is journalist Josette Rigsby from CMS Wire. The contest will run until Sunday, May 20 at midnight US/Pacific. The rules are simple:

  • Reply to the Liferay tweet in the 140-character limit.
  • Include the two hashtags #supdev and #liferay in your tweet.
  • Be creative and have fun.

The participant with the best answer will receive a unique and fun prize. Two runners-up also receive prizes.

More about our guest judge

Josette Rigsby is an enterprise architect with more than 15 years experience leading information technology teams. Her articles for CMS Wire cover a wide range of enterprise CMS topics including open-source technologies, cloud-based software development and other tech trends. She has written extensively about Liferay for CMS Wire, including stories this year that tracked the growth of the Liferay community and her take on the launch of Liferay Portal 6.1. Follow her at @techielicous for her latest articles, and follow her on Google+ for entertaining posts about technology and culture.

Prizes

Three winners will receive one out of a set of fabulous prizes!

Col. Fezziwig's Eccid Blaster Steampunk Ray Gun

This Eccid Blaster replica ray gun hearkens back to the days of Jules Verne and H.G. Wells. Like something out of a Tom Swift novel, the Blaster features incredible detail, hand-painted accents and has a removable "laser" cartridge on top.

Sphero!

The Sphero is simply a robotic ball that rolls around on the floor and is controlled through a virtual joystiq on your smartphone. After you’re finished being easily amused with your control over a plastic ball, download the free apps and have some more fun playing Sphero-integrated games such as a side-scrolling space game and even golf.

Arduino Uno Starter Kit

The Arduino Uno is a microcontroller board based on the ATmega328 (datasheet). It has 14 digital input/output pins (of which 6 can be used as PWM outputs), 6 analog inputs, a 16 MHz crystal oscillator, a USB connection, a power jack, an ICSP header, and a reset button.  Pefect for the tinkerer in you!

Hungary Community Meetup

Staff Blogs 25 aprile 2012 Da James Falkner Staff

If you are attending this year's Liferay Hungary Symposium next month in Budapest, also plan on attending the Liferay Hungary Community Meetup on May 16 (the evening prior to the symposium). This will be a free event, starting around 18:00 (possible a little later or earlier, depending on when the pre-symposium training completes!), at Zydeco Bar [enjoy some pictures]. Come meet your fellow community members (and friendly community managers), Liferay staff, and other interested parties with some free drinks, snacks, and interesting conversation! It'll be a great way to start off your symposium. If you are interested in attending, you must let us know by sending an email to events-hu@liferay.com!  Space is limited, as Zydeco is really cozy, so everyone will be friends by the end. See you in Budapest!

Liferay and Web Experience Standards

Staff Blogs 13 aprile 2012 Da James Falkner Staff

Liferay has a long history of participation in and implementation of various standards in web software over the years. Notably, Liferay has participated in development of JSR-286 (Portlet 2.0), JSR-314 (JSF 2.0), WSRP, and CMIS. Liferay is once again participating in a new standard called WEMI (Web Experience Management Interoperability).

The Technical Committee for WEMI had its first Face-to-Face meeting earlier this month in Copenhagen (big thanks to Sitecore who hosted all of us!), and I attended as a Liferay representative. You can read the meeting minutes here (thanks to Peeter from Adobe!).  It's a bit of a departure from my ordinary duties as community manager, but as a long time user of Liferay's WCM (both UI and API), knowledge of our community's use of (and issues encountered in) Liferay, and with some experience in standards development, it is an interesting role to play for me. I had low expectations given it was the first meeting, the number of participants was large, and no agenda set for the meeting, but was pleasantly surprised by level of knowledge and experience of the group, our ability to stay focused on the getting work done, and the amount of agreement on basic problems.

The funny thing is, I believe that most if not all of the vendors present have already implemented much of what WEMI seeks to standardize, but in a proprietary way, so in that regard I believe it is a ripe area for standardization. Of course, the moment we all got in the same room, the scope and goals of the TC started to evolve, but that's not surprising either. I think the general consensus is that there is some meat to this (after all, if you thought the goals were bogus, you probably wouldn't participate), but in order to build interest and excitement, ensure broad adoption, and keep the TC engaged, we need first to declare some real world use cases for WEMI, useful problems that it can solve that cannot be solved today (through existing standards or existing tools), so we'll be working on those first. There are a couple that have been put on the table, such as site content indexing/archive/retrieval (especially across versions of a CMS, such as when upgrading Liferay), or providing additional context around content objects, for use by social engagement systems. Serge (Jahia) has an excellent pre- and post-writeup in this regard.

It's also important to keep it small and simple, while still providing real value in the first iteration. A 1.0 spec that simply sets the groundwork for 2.0 is a waste of time, because no one will stick around for 2.0 due to lack of adoption. So on that topic we all agreed as well. Also, as Boris (Magnolia) states, we mustn't make yet another "hierarchical nodes and data elements" standard -- we already have a couple of those, and it reminds me of this excellent XKCD comic:

WEMI must focus its efforts at a level above things like CMIS (in fact, WEMI started during CMIS development, where some participants felt it was missing several key parts to CMS interoperability) if it is to provide real value.

So, what's in it for Liferay?

Why would Liferay participate and implement such a standard?  There are many reasons, but here are some:

  • It's currently hard to programmatically aggregate and mashup content from Liferay for use in a browser or mobile device. Yes, you can use our JSON-friendly APIs to get at content, or our Java APIs, but you have to do a lot of groundwork to even get to the point where you can call the APIs and understand what you can do with it. This is one of the reasons we have things like the Asset Publisher (which does a lot of that groundwork for you) and the ability to export portlet content as widgets, neither of which give you programmatic access to the content and its associated metadata.
  • While documentation is improving, it's still not close to 100%, so there are many APIs and domain models that have little or no documentation.
  • Content archive/retrieval is done through import/export, but a) it's unusable across different versions of Liferay, and b) its format (LAR) is also mostly undocumented (though it's somewhat easy to infer its contents if you know a lot about Liferay's architecture), but in general only Liferay knows what to do with them.
  • Liferay provides a lot of functionality wrapped around content (versioning, workflow, social, etc) but most of this is stripped out or opaque when accessing content through content APIs. You have to do a bunch of extra work to find this additional data and relate it to the content.
  • Liferay customers often wish to aggregate web content from other systems, so having a good understanding of this up and coming standard will help us implement it faster.

A standard also forces implementers to adhere to the published, documented, (and in cases of a good standard) well-understood spec - and WEMI in particular (with its goal of simplicity and usefulness out of the gate) will define context and content metadata such that interesting content-centric functionality provided by vendors is exposed in a well known and consistent way.

Other Aspects

There were many other topics broached during the meeting, and I've included a few notable ones here:

  • Since in general, reuse/recycling is a good thing in many aspects of life, the group also recognizes that there could be existing standards that could be co-opted for use by WEMI as building blocks (for example, semantic constructs from HTML5 such as <article>, or build WEMI on top of OData and borrowing their querying capabilities) and more investigation is ongoing.
  • Content may appear to be arranged as a hierarchy when viewed in the context of a desktop website, but content served to a mobile device may have an entirely different organization. WEMI should allow for this.
  • Serialization/representational formats/protocol bindings: Let's stick with formats friendly to the consumers we are targeting with WEMI: meaning, let's use JSON and HTML, not XML and/or SOAP.
  • Access Control is specifically out of scope for WEMI (too complex, no least common denominator, etc), but the concept of contexts and personalization may prove useful. Contexts allow you to declare the purpose/destination of content during the retrieval/aggregation, so that even more aggregation work is done for you by the CMS.

In summary, I think this working group works well together, no one showed up and dropped a fully baked implementation and said "this is where we start", and I think we will make quick work of this and have something quite useful quite quickly.  So, I am looking forward to getting into it!

 

Risultati 21 - 40 su 85.
Items 20
di 5