Java GuestApp API Tutorial 5-5
Java GuestApp API Tutorial 5-5
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springapp</groupId>
<artifactId>Calculator</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<repositories>
<repository>
<id>codelds</id>
<url>https://code.lds.org/nexus/content/groups/main-repo</url>
</repository>
<repository>
<id>apprenda-public</id>
<name>Apprenda Public</name>
<url>https://raw.github.com/Apprenda/mvn-repo/releases</url>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<apprenda.artifactversion>5.0.4-Release</apprenda.artifactversion>
<spring.version>4.0.5.RELEASE</spring.version>
<jre.version>1.7</jre.version>
<persistence.backend>oracle</persistence.backend>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.6.0.RELEASE</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.5.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.1.Final</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.apprenda</groupId>
<artifactId>javautils-datasource</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.apprenda.framework</groupId>
<artifactId>guestapp-api</artifactId>
<version>${apprenda.artifactversion}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>sqlserver</id>
<properties>
<jdbc.driver>net.sourceforge.jtds.jdbc.Driver</jdbc.driver>
<jdbc.url>jdbc:jtds:sqlserver://localhost:1433/Calculator</jdbc.url>
<jdbc.user>sqladmin</jdbc.user>
<jdbc.password>password</jdbc.password>
<persistence.backend>sqlserver</persistence.backend>
<persistence.dbms>mssql</persistence.dbms>
<jpa.hibernate.dialect>org.hibernate.dialect.SQLServerDialect</jpa.hibernate.dialect>
</properties>
<dependencies>
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>oracle</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<jdbc.driver>oracle.jdbc.OracleDriver</jdbc.driver>
<jdbc.url>jdbc:oracle:thin:@//localhost:1522</jdbc.url>
<jdbc.user>oracleadmin</jdbc.user>
<jdbc.password>password</jdbc.password>
<persistence.backend>oracle</persistence.backend>
<persistence.dbms>oracle</persistence.dbms>
<jpa.hibernate.dialect>org.hibernate.dialect.Oracle10gDialect</jpa.hibernate.dialect>
</properties>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
</dependency>
</dependencies>
</profile>
</profiles>
<build>
<finalName>Calculator</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${jre.version}</source>
<target>${jre.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<finalName>${project.build.finalName}-${jre.version}${persistence.backend</finalName>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- this is used for inheritance merges -->
<phase>package</phase>
<!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Figure 2
CalculationRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CalculationRepository
extends JpaRepository<Calculation, Long> {
}
Figure 3
Calculation.java
import javax.persistence.*;
import java.io.Serializable;
@Entity(name = "calculation")
public class Calculation implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Basic
private double operand1;
@Basic
private double operand2;
@Basic
private char operator;
@Basic
private String result;
@Basic
private String userEmail;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public double getOperand1() { return operand1; }
public void setOperand1(double operand1) {
this.operand1 = operand1;
}
public double getOperand2() { return operand2; }
public void setOperand2(double operand2) {
this.operand2 = operand2;
}
public char getOperator() { return operator; }
public void setOperator(char operator) {
this.operator = operator;
}
public String getResult() { return result; }
public void setResult(String result) { this.result = result; }
public String getUserEmail() { return userEmail; }
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
}
Figure 4
ICalculatorService.java
import com.apprenda.calculator.entity.Calculation;
import java.util.List;
public interface ICalculatorService {
public String add(final Calculation calculation);
public String subtract(final Calculation calculation);
public String multiply(final Calculation calculation);
public String divide(final Calculation calculation);
public String squareRoot(final Calculation calculation);
public List<Calculation> getCalculations();
public void storeCalculation(final Calculation calculation);
public void deleteCalculation(final Long calculationId);
}
Figure 5
CalculatorService.java
package com.apprenda.calculator.service;
import
import
import
import
com.apprenda.calculator.entity.Calculation;
com.apprenda.calculator.entity.CalculationRepository;
org.springframework.beans.factory.annotation.Autowired;
java.util.List;
mvc-dispatcher-servlet.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.apprenda.calculator.controller"/>
<mvc:annotation-driven/>
<jpa:repositories base-package="com.apprenda.calculator.entity"/>
<bean id="calculatorService"
class="com.apprenda.calculator.service.CalculatorService"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- Load in application properties reference -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="apprendaDataSource"
class="com.apprenda.guest.data.ApprendaSimpleDataSource">
<property name="driverClass" value="${jdbc.driver.class}"/>
<property name="jdbcUrl" value="${jdbc.url.name}"/>
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Calculator</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servletclass>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Figure 8
calculator.jsp
<!doctype
<%@taglib
<%@taglib
<%@taglib
<%@taglib
html>
uri="http://www.springframework.org/tags" prefix="spring" %>
uri="http://www.springframework.org/tags/form" prefix="form" %>
uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Calculator</title>
</head>
<body>
<h1 style="text-align: center;">Calculator</h1>
<div class="container">
<div class="calculator">
<form:form method="post" align="center" action="do_calculate"
commandName="calculation" id="do_calculate"
class="form-inline">
<label>Operand 1:</label>
<spring:bind path="calculation.operand1">
<form:input type="text" path="operand1" class="span2"/>
</spring:bind>
<br/>
<br/>
<label>Operator:</label>
<spring:bind path="calculation.operator">
<form:select id="operator" name="operator" path="operator"
class="span2">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
<option value="R">√</option>
</form:select>
</spring:bind>
<br/>
<br/>
<label>Operand 2:</label>
<spring:bind path="calculation.operand2">
<form:input type="text" path="operand2" class="span2"/>
</spring:bind>
<br/>
<br/>
<br/>
<input type="submit" class="btn btn-success" value="Calculate"/>
<c:if test="${message != null}">
<div class="alert">${message}</div>
</c:if>
</form:form>
</div>
<div>
<c:if test="${!empty calculations}">
CalculatorController.java
import
import
import
import
import
import
import
import
import
import
import
import
com.apprenda.calculator.entity.Calculation;
com.apprenda.calculator.service.CalculatorService;
org.apache.log4j.Logger;
org.springframework.beans.factory.annotation.Autowired;
org.springframework.stereotype.Controller;
org.springframework.ui.ModelMap;
org.springframework.validation.BindingResult;
org.springframework.web.bind.annotation.ModelAttribute;
org.springframework.web.bind.annotation.PathVariable;
org.springframework.web.bind.annotation.RequestMapping;
org.springframework.web.bind.annotation.RequestMethod;
org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
@Controller
@RequestMapping("/")
public class CalculatorController {
private static Logger logger=Logger.getLogger(CalculatorController.class);
@Autowired
CalculatorService service;
@RequestMapping(value = "/do_calculate", method = RequestMethod.POST)
public String calculate(ModelMap model, @Valid
@ModelAttribute("calculation") Calculation calculation,
BindingResult binding, HttpSession session) {
String result = " ";
switch (calculation.getOperator()) {
case '+':
result = service.add(calculation);
break;
case '-':
result = service.subtract(calculation);
break;
case '*':
result = service.multiply(calculation);
break;
case '/':
result = service.divide(calculation);
break;
case 'R':
result = service.squareRoot(calculation);
break;
}
service.storeCalculation(calculation);
model.addAttribute("calculation", new Calculation());
model.addAttribute("calculations", service.getCalculations());
logger.info("Calculated " + calculation.getOperand1() + " " +
calculation.getOperator() + " " + calculation.getOperand2() +
" = " + result);
return "redirect:/";
}
@RequestMapping(value = "/", method = RequestMethod.GET)
public String listCalculations(ModelMap model, HttpSession session) {
model.addAttribute("calculations", service.getCalculations());
model.addAttribute("calculation", new Calculation());
return "calculator";
}
@RequestMapping("/delete/{calculationId}")
public String deleteTask(@PathVariable("calculationId") Long
calculationId, final RedirectAttributes redirectAttributes) {
service.deleteCalculation(calculationId);
logger.info("Deleted calculation with id = " +
calculationId.toString());
redirectAttributes.addFlashAttribute("message", "Calculation deleted.");
return "redirect:/";
}
}
Figure 10
db.properties
jdbc.driver.class=${jdbc.driver}
jdbc.url.name=${jdbc.url}
jdbc.user=${jdbc.user}
jdbc.password=${jdbc.password}
Figure 11
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="defaultPersistenceUnit" transactiontype="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.dialect" value="${jpa.hibernate.dialect}" />
</properties>
</persistence-unit>
</persistence>
Figure 12
1.
2.
3.
ApplicationProvisioning_Script.pls
CREATE TABLE CALCULATION(
id number(19, 0) NOT NULL,
OPERAND1 VARCHAR2(255) NOT NULL,
OPERATOR CHAR NULL,
OPERAND2 VARCHAR2(255) NOT NULL,
RESULT VARCHAR2(255) NULL,
USEREMAIL VARCHAR2(255) NULL,
PRIMARY KEY (id)
)
ORGANIZATION INDEX;
CREATE SEQUENCE hibernate_sequence INCREMENT BY 1;
CREATE OR REPLACE TRIGGER BI_CALCULATION
before insert on CALCULATION
for each row
begin
if :NEW.ID is null then
:NEW.ID := hibernate_sequence.nextval;
end if;
end;
Figure 13
1.
2.
3.
ApplicationProvisioning_Script.sql
CREATE TABLE [dbo].[calculation](
[id] [numeric](19, 0) IDENTITY(1,1) NOT NULL,
[operand1] [varchar](255) NOT NULL,
[operator] [char](1) NOT NULL,
[operand2] [varchar](255) NOT NULL,
[result] [varchar](255) NULL,
[userEmail] [varchar](255) null,
PRIMARY KEY CLUSTERED ([id] ASC)
);
Figure 14
CalculatorController.java
public class CalculatorController {
private static
private static
private static
private static
private static
Calculations";
Figure 15
final
final
final
final
final
String
String
String
String
String
CalculatorController.java
GuestAppContext guestCtx = ApprendaGuestApp.getContext();
Figure 16
CalculatorController.java
calculation.setUserEmail(guestCtx.getUser().getEmail());
Figure 17
CalculatorController.java
ToggleMeter toggleMeter
BlockMeter blockMeter =
BoundMeter boundMeter =
LimitMeter limitMeter =
Figure 18
= guestCtx.getMeters().getToggle(TOGGLE_METER_NAME);
guestCtx.getMeters().getBlock(BLOCK_METER_NAME);
guestCtx.getMeters().getBound(BOUND_METER_NAME);
guestCtx.getMeters().getLimit(LIMIT_METER_NAME);
CalculatorController.java
case '+':
if (!toggleMeter.isEnabled()) {
model.addAttribute("message", "Your subscription does not allow addition or
subtraction");
model.addAttribute("calculations", service.getCalculations());
return "calculator";
}
result = service.add(calculation);
break;
case '-':
if (!toggleMeter.isEnabled()) {
model.addAttribute("message", "Your subscription does not allow addition or
subtraction");
model.addAttribute("calculations", service.getCalculations());
return "calculator";
}
result = service.subtract(calculation);
break;
Figure 19
CalculatorController.java
case '*':
if (blockMeter.isExhausted()) {
model.addAttribute("message", "You have used up you allowed
multiplication and division calculations");
model.addAttribute("calculations", service.getCalculations());
return "calculator";
}
result = service.multiply(calculation);
// Decrease the number of remaining mult/div calculations
blockMeter.decrement();
break;
case '/':
if (blockMeter.isExhausted()) {
model.addAttribute("message", "You have used up you allowed
multiplication and division calculations");
model.addAttribute("calculations", service.getCalculations());
return "calculator";
}
result = service.divide(calculation);
// Decrease the number of remaining mult/div calculations
blockMeter.decrement();
break;
Figure 20
CalculatorController.java
case 'R':
if (boundMeter.isAboveBound((float)
(Math.abs(calculation.getOperand1())))) {
double boundValue = boundMeter.getState().getValue();
model.addAttribute("message", "Your subscription allow allows
roots within ( -" + boundValue + ", " + boundValue + " )");
model.addAttribute("calculations", service.getCalculations());
model.addAttribute("calculation", new Calculation());
return "calculator";
}
result = service.squareRoot(calculation);
break;
Figure 21
CalculatorController.java
if (limitMeter.getState().isExhausted()) {
model.addAttribute("message", "Your have stored the maximum number of
calculations allowed by your subscription.");
model.addAttribute("calculations", service.getCalculations());
return "calculator";
}
service.storeCalculation(calculation);
limitMeter.increment();
Figure 22
square
CalculatorController.java
@RequestMapping("/delete/{calculationId}")
public String deleteTask(@PathVariable("calculationId") Long calculationId, final
RedirectAttributes redirectAttributes) {
GuestAppContext guestCtx = ApprendaGuestApp.getContext();
LimitMeter limitMeter = guestCtx.getMeters().getLimit(LIMIT_METER_NAME);
if(!guestCtx.getAppVersion().hasAccessToStatic(
DELETE_CALCULATIONS_SECURABLE_NAME))
{
redirectAttributes.addFlashAttribute("message", "You are not allowed
to delete calculations.");
return "redirect:/";
}
service.deleteCalculation(calculationId);
limitMeter.decrement();
logger.info("Deleted calculation with id = " + calculationId.toString());
redirectAttributes.addFlashAttribute("message", "Calculation deleted.");
return "redirect:/";
}
Figure 23
DeploymentManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<appManifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.apprenda.com/DeploymentManifest"
xsi:schemaLocation="http://schemas.apprenda.com/DeploymentManifest
http://apprenda.com/schemas/platform/5.0/DeploymentManifest.xsd">
<!--Valid values for applicationServices level: "None", "Authentication", "Authorization",
"Multitenancy", "Billing"-->
<applicationServices level="Multitenancy"/>
<executionSecurables>
<securable name="Delete Calculations"/>
</executionSecurables>
<persistence dbms="${persistence.dbms}" strategy="IsolatedDB">
</persistence>
<features>
<toggle name="Add and Subtract"/>
<block name="Multiply and Divide"/>
<boundary name="Square Root Max"/>
<limiter name="Number of Calculations"/>
</features>
<wars>
<war name="Calculator.war" javaVersion="Default JRE 1.7">
</war>
</wars>
<entitlementDefinitions>
<entitlementDefinition name="Standard" description="" isPublished="true">
<accountWideEntitlements>
<plans>
<plan name="Basic Account" description="" planType="Perpetual"
restrictionOnNumberOfSubscriptions="1">
<planModels>
<planModel type="Perpetual" />
</planModels>
</plan>
<plan name="Deluxe Account" description="" planType="Perpetual"
restrictionOnNumberOfSubscriptions="1">
<planModels>
<planModel type="Perpetual" />
</planModels>
</plan>
</plans>
<sections>
<section>
<components>
<component displayName="Number of Calculations" feature="Number of Calculations"
description="" isHidden="false" isNew="false">
<planItems>
<planItem plan="Basic Account" inclusionStatus="Included">
<planItemDefinitions>
<planItemDefinition type="Perpetual" quantity="5" planModelType="Perpetual" />
</planItemDefinitions>
</planItem>
<planItem plan="Deluxe Account" inclusionStatus="Included">
<planItemDefinitions>
<planItemDefinition type="Perpetual" quantity="100" planModelType="Perpetual" />
</planItemDefinitions>
</planItem>
</planItems>
</component>
</components>
</section>
</sections>
</accountWideEntitlements>
<userBasedEntitlements>
<plans>
<plan name="Basic User" planType="Periodic" >
<planModels>
<planModel refreshInterval="every 7 days" />
</planModels>
</plan>
<plan name="Deluxe User" planType="Periodic" >
<planModels>
<planModel refreshInterval="every 1 year" />
</planModels>
</plan>
</plans>
<sections>
<section>
<components>
<component displayName="Add and Subtract" feature="Add and Subtract" isNew="true">
<planItems>
<planItem plan="Deluxe User" inclusionStatus="Included">
<planItemDefinitions>
<planItemDefinition planModelRefreshInterval="every 1 year" />
</planItemDefinitions>
</planItem>
</planItems>
</component>
<component displayName="Multiply and Divide" feature="Multiply and Divide"
isHidden="false">
<planItems>
<planItem plan="Basic User" inclusionStatus="Included">
<planItemDefinitions>
<planItemDefinition planModelRefreshInterval="every 7 days" blockLabel="Multiply and
Divide" quantity="10" />
</planItemDefinitions>
</planItem>
<planItem plan="Deluxe User" inclusionStatus="Included">
<planItemDefinitions>
<planItemDefinition planModelRefreshInterval="every 1 year" blockLabel="Multiply and
Divide" quantity="999" />
</planItemDefinitions>
</planItem>
</planItems>
</component>
<component displayName="Square Root Max" feature="Square Root Max" isHidden="false">
<planItems>
<planItem plan="Basic User" inclusionStatus="Included">
<planItemDefinitions>
<planItemDefinition planModelRefreshInterval="every 7 days" quantity="100" />
</planItemDefinitions>
</planItem>
<planItem plan="Deluxe User" inclusionStatus="Included">
<planItemDefinitions>
<planItemDefinition planModelRefreshInterval="every 1 year" quantity="10000" />
</planItemDefinitions>
</planItem>
</planItems>
</component>
</components>
</section>
</sections>
</userBasedEntitlements>
</entitlementDefinition>
</entitlementDefinitions>
</appManifest>
Figure 24
assembly.xml
<?xml version="1.0" encoding="windows-1252"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assemblyplugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assemblyplugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>apprenda-webapp</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/apprenda</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>DeploymentManifest.xml</exclude>
<exclude>persistence/**</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.basedir}/src/main/apprenda</directory>
<outputDirectory>/</outputDirectory>
<filtered>true</filtered>
<includes>
<include>DeploymentManifest.xml</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.basedir}/src/main/apprenda/persistence/${persistence.backend}<
/directory>
<outputDirectory>/persistence</outputDirectory>
<filtered>true</filtered>
<includes>
<include>**/*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/wars/${project.build.finalName}.war</outputDirectory>
<includes>
<include>${project.build.finalName}.war</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Figure 25
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<finalName>${project.build.finalName}-${jre.version}</finalName>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- this is used for inheritance merges -->
<phase>package</phase>
<!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Figure 26
Figure 27
Figure 28
Figure 29
Figure 30
Figure 31
navigate to the Legacy Portal using the previously-described steps, and then
click the Applications link in the top menu bar.
5. Click on Super Calculator in the Application List, then click Version 1.
Figure 32
Figure 33
CalculatorController.java
if (limitMeter.getState().isExhausted()) {
model.addAttribute("message", "Your have stored the maximum number of
calculations allowed by your subscription; please delete stored calculations.");
model.addAttribute("calculations", service.getCalculations());
return "calculator";
}
service.storeCalculation(calculation);
limitMeter.increment();
Figure 34
Figure 35
Figure 36
Figure 36