Skip to content

Commit

Permalink
Merge branch 'release/3.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrosan7os committed Jul 18, 2014
2 parents 18248fb + d445684 commit f4dcd54
Show file tree
Hide file tree
Showing 241 changed files with 4,283 additions and 11,312 deletions.
54 changes: 35 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Bennu - Modular Web App Development for Java
# Bennu - Modular Web App Development for Java [![Build Status](https://travis-ci.org/FenixEdu/bennu.svg?branch=develop)](https://travis-ci.org/FenixEdu/bennu)

Bennu is the foundation for building modular Java web applications based on the [fenix-framework](http://fenix-framework.github.io/).

Expand All @@ -18,55 +18,71 @@ Bennu covers the following core features:

### Basic setup

* __step 1__ Create a mysql database for your project
* __Step 1__ Create a mysql database for your project

* __step 2__ Create a web-app project:
* __Step 2__ Create a web-app project:
```
mvn archetype:generate \
-DarchetypeGroupId=org.fenixedu \
-DarchetypeArtifactId=bennu-webapp-archetype \
-DarchetypeVersion=3.0.0 \
-DarchetypeVersion=3.2.0 \
-DarchetypeRepository=https://fenix-ashes.ist.utl.pt/nexus/content/groups/fenix-ashes-maven-repository
```
suplying the database information as requested
Make sure to supply the information required by the archetype.

* __step 3__ Run ```mvn package jetty:run``` on the newly created project and it's up and running
> Due to a limitation with Maven, you cannot select an empty database password.
> If your password is empty, choose any, and edit the 'src/main/resources/fenix-framework.properties' file.
* __step 4__ Access [http://localhost:8080/web-app-artifactId](http://localhost:8080/)
* __Step 3__ Run ```mvn tomcat7:run``` on the newly created project and it's up and running

* __step 5__ Login a user without supplying any password, this will be your manager account for now.
* __Step 4__ Open your application at [http://localhost:8080/](http://localhost:8080/)

* __step 6__ Access Admin>Configuration link and set the name and other details of your App
* __Step 5__ Follow the on-screen bootstrap guide, which will ask your for some initial system configurations.

* __Step 6__ Once you hit finish, you should see the initial screen of your application. To login, simply
click the 'Login' button on the upper right corner, and enter the username you chose in the
previous step.

* __Step 7__ Click on the 'System Management' and you are now able to select which functionalities your
application provides.

### Creating an hello world module

* __step 7__ Create a library project using
* __Step 1__ Create a library project using
```
mvn archetype:generate \
-DarchetypeGroupId=org.fenixedu \
-DarchetypeArtifactId=bennu-project-archetype \
-DarchetypeVersion=3.0.0 \
-DarchetypeVersion=3.2.0 \
-DarchetypeRepository=https://fenix-ashes.ist.utl.pt/nexus/content/groups/fenix-ashes-maven-repository
```

* __step 8__ Open the file ```src/main/webapp/hello-world/index.html``` and set it's contents to:
> The following steps assume you named your application 'hello-world'. If that is not the case,
> replace 'hello-world' with the name you chose.
* __Step 2__ Open the file ```src/main/webapp/hello-world/index.jsp``` and set it's contents to:
```
<h1>Hello World</h1>
```

* __step 9__ Open the file ```src/main/resources/hello-world/apps.json``` and set it's contents to:
* __Step 3__ Open the file ```src/main/resources/apps.json``` and set it's contents to:
```
{"apps" :
[{
{"apps": [{
"title": { "en-GB" : "Hello World", "pt-PT": "Olá Mundo" },
"description": { "pt-PT": "O meu primeiro módulo Bennu", "en-GB": "My First Bennu Module" },
"accessExpression": "anyone",
"path": "hello-world",
"functionalities": [{
"title" : {"en-GB" : "Hello World", "pt-PT": "Olá Mundo"},
"description" : {"en-GB" : "Greets people warmly", "pt-PT": "Saúda pessoas afectivamente"},
"accessExpression" : "#anyone",
"path" : "hello-world",
"accessExpression": "anyone",
"path": "#"
}]
}
}]}
```

* __step 10__ Access Admin>Menu Configuration and add the hello world functionality in any place of the menu, then access it and get greeted
* __Step 4__ Add your newly created module to your application, and install it using the System Management tool.
Your app should now be available in the application's menu.

## What's next?

Expand Down
2 changes: 1 addition & 1 deletion bennu-portal/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.fenixedu</groupId>
<artifactId>bennu</artifactId>
<version>3.1.0</version>
<version>3.2.0</version>
</parent>

<artifactId>bennu-portal</artifactId>
Expand Down
2 changes: 2 additions & 0 deletions bennu-portal/src/main/dml/bennu-portal.dml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public class PortalConfiguration {
public String systemEmailAddress;
public bytearray logo;
public String logoType;
public String logoLinkUrl;
public String logoTooltip;
public bytearray favicon;
public String faviconType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@ public SemanticURLHandler getSemanticURLHandler() {
@Override
public void handleRequest(MenuFunctionality functionality, HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
String forwardUrl =
"/" + functionality.getParent().getPath() + "/"
+ (functionality.getPath().startsWith("#") ? "" : functionality.getPath());
request.getRequestDispatcher(forwardUrl).forward(request, response);
}
};
}

@Override
public boolean requiresServerSideLayout() {
return false;
return true;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ public MenuContainer(MenuContainer parent, boolean visible, String accessGroup,
init(parent, visible, accessGroup, title, description, path);
}

/*
* Creates a new copy of this container. It does NOT replicate the container's children.
*/
private MenuContainer(MenuContainer parent, MenuContainer original) {
super();
if (parent == null) {
throw new IllegalArgumentException("MenuFunctionality cannot be created without a parent!");
}
init(parent, original);
}

/**
* Adds a given {@link MenuItem} as the last child of this container.
*
Expand Down Expand Up @@ -267,4 +278,26 @@ public MenuFunctionality findInitialContent() {
}
return null;
}

/**
* "Moves" this container to the selected point in the menu.
*
* As {@link MenuItem}s are immutable by default, this instance is deleted, and
* a new copy of it is created under the specified container. This process is
* recursive, meaning that all the current children will be replicated as well.
*
* @param newParent
* The new parent in which to insert the copy of this container
* @return
* The newly created container
*/
@Override
public MenuContainer moveTo(MenuContainer newParent) {
MenuContainer copy = new MenuContainer(newParent, this);
for (MenuItem item : getChildSet()) {
item.moveTo(copy);
}
super.delete();
return copy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ public MenuFunctionality(MenuContainer parent, boolean visible, String key, Stri
setProvider(provider);
}

/*
* Creates a new copy of this functionality under the specified parent.
*/
private MenuFunctionality(MenuContainer newParent, MenuFunctionality original) {
super();
if (newParent == null) {
throw new IllegalArgumentException("MenuFunctionality cannot be created without a parent!");
}
init(newParent, original);
setItemKey(original.getItemKey());
setProvider(original.getProvider());
}

/**
* Looks up in the functionality tree, the functionality with the given provider and key.
*
Expand Down Expand Up @@ -79,6 +92,24 @@ public String getItemKey() {
return super.getItemKey();
}

/**
* "Moves" this functionality to the selected point in the menu.
*
* As {@link MenuItem}s are immutable by default, this instance is deleted, and
* a new copy of it is created under the specified container.
*
* @param newParent
* The new parent in which to insert the copy of this functionality
* @return
* The newly created functionality
*/
@Override
public MenuFunctionality moveTo(MenuContainer newParent) {
MenuFunctionality copy = new MenuFunctionality(newParent, this);
delete();
return copy;
}

// Private methods

private static MenuFunctionality findFunctionality(MenuContainer container, String provider, String key) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ protected final void init(MenuContainer parent, boolean visible, String accessGr
setFullPath(computeFullPath());
}

protected final void init(MenuContainer parent, MenuItem original) {
setVisible(original.getVisible());
setAccessGroup(original.getAccessGroup());
setDescription(original.getDescription());
setTitle(original.getTitle());
setPath(original.getPath());
setLayout(original.getLayout());
if (parent != null) {
parent.addChild(this);
}
setFullPath(computeFullPath());
}

public Group getAccessGroup() {
return getGroup().toGroup();
}
Expand Down Expand Up @@ -175,4 +188,6 @@ public List<MenuItem> getPathFromRoot() {
}
return result;
}

protected abstract MenuItem moveTo(MenuContainer container);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.fenixedu.bennu.portal.servlet.PortalInitializer;
import org.fenixedu.commons.i18n.LocalizedString;

import com.google.common.base.Strings;
import com.google.common.io.BaseEncoding;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
Expand All @@ -36,6 +37,12 @@ public JsonElement view(PortalConfiguration configuration, JsonBuilder ctx) {
if (configuration.getLogo() != null) {
object.addProperty("logo", BaseEncoding.base64().encode(configuration.getLogo()));
object.addProperty("logoType", new String(configuration.getLogoType()));
if (!Strings.isNullOrEmpty(configuration.getLogoLinkUrl())) {
object.addProperty("logoLinkUrl", configuration.getLogoLinkUrl());
}
if (!Strings.isNullOrEmpty(configuration.getLogoTooltip())) {
object.addProperty("logoTooltip", configuration.getLogoTooltip());
}
}
if (configuration.getFavicon() != null) {
object.addProperty("favicon", BaseEncoding.base64().encode(configuration.getFavicon()));
Expand Down Expand Up @@ -80,6 +87,12 @@ public PortalConfiguration update(JsonElement json, PortalConfiguration configur
if (object.has("logoType")) {
configuration.setLogoType(object.get("logoType").getAsString());
}
if (object.has("logoLinkUrl")) {
configuration.setLogoLinkUrl(object.get("logoLinkUrl").getAsString());
}
if (object.has("logoTooltip")) {
configuration.setLogoTooltip(object.get("logoTooltip").getAsString());
}
if (object.has("favicon")) {
configuration.setFavicon(BaseEncoding.base64().decode(object.get("favicon").getAsString()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.fenixedu.bennu.portal.servlet;

import javax.servlet.ServletContext;

import org.fenixedu.bennu.core.json.adapters.AuthenticatedUserViewer;
import org.fenixedu.bennu.core.rest.BennuRestResource;

/**
* The goal of this bean is to allow easy injection of Bennu Portal variables in JSP pages.
*
* Refer to each individual method for its documentation.
*
* @author João Carvalho ([email protected])
*
*/
public class PortalBean {

private final String ctxPath;

public PortalBean(ServletContext servletContext) {
this.ctxPath = servletContext.getContextPath();
}

/**
* Injects a Javascript context with contains the {@code BennuPortal} variable, which is a subset
* of the Bennu Portal Data REST API, containing information about the configured locales, the current
* locale, as well as some information regarding the currently logged user.
*
* If also sets up the {@code contextPath} variable, which contains the configured context path of the
* application.
*
* @return
* A {@code <script>} tag containing the {@code BennuPortal} and {@code contextPath} variables.
*/
public String bennuPortal() {
StringBuilder builder = new StringBuilder();
builder.append("<script>");
{
builder.append("window.BennuPortal = ");
builder.append(BennuRestResource.getBuilder().view(null, Void.class, AuthenticatedUserViewer.class)).append(";");
}
{
builder.append("window.contextPath = '").append(ctxPath).append("';");
}
builder.append("</script>");
return builder.toString();
}
}
Loading

0 comments on commit f4dcd54

Please sign in to comment.