You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by ca...@apache.org on 2011/08/17 20:07:10 UTC
svn commit: r1158852 - in /incubator/rave/trunk: ./
rave-commons/src/main/java/org/apache/rave/exception/
rave-commons/src/test/java/org/apache/rave/exception/
rave-portal/src/main/java/org/apache/rave/portal/model/
rave-portal/src/main/java/org/apache...
Author: carlucci
Date: Wed Aug 17 18:07:09 2011
New Revision: 1158852
URL: http://svn.apache.org/viewvc?rev=1158852&view=rev
Log:
RAVE-199: Add a new Page to Rave. This is a sub-task of RAVE-163: Page Management CRUD. This checkin also includes some common code that was needed - creating an architecture for handling and converting database specific exceptions into Rave exceptions
Added:
incubator/rave/trunk/rave-commons/src/main/java/org/apache/rave/exception/DuplicateItemException.java
- copied, changed from r1158276, incubator/rave/trunk/rave-commons/src/main/java/org/apache/rave/exception/NotSupportedException.java
incubator/rave/trunk/rave-commons/src/test/java/org/apache/rave/exception/DuplicateItemExceptionTest.java
- copied, changed from r1158818, incubator/rave/trunk/rave-commons/src/test/java/org/apache/rave/exception/NotSupportedExceptionTest.java
incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/repository/impl/H2OpenJpaDialect.java
incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/repository/impl/TranslatedH2Exception.java
incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/RepositoryTestUtils.java
incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/impl/H2OpenJpaDialectTest.java
incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/impl/TranslatedH2ExceptionTest.java
Modified:
incubator/rave/trunk/ (props changed)
incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/Page.java
incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/PageService.java
incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultNewAccountService.java
incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java
incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/model/RpcOperation.java
incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/model/RpcResult.java
incubator/rave/trunk/rave-portal/src/main/resources/portal.properties
incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/applicationContext.xml
incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp
incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_api.js
incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_forms.js
incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_layout.js
incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/AbstractJpaRepositoryTest.java
incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/service/PageServiceTest.java
incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java
incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/model/RpcOperationTest.java
incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/model/RpcResultTest.java
incubator/rave/trunk/rave-portal/src/test/javascript/raveApiSpec.js
Propchange: incubator/rave/trunk/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Aug 17 18:07:09 2011
@@ -1,5 +1,4 @@
-target
-
.project
-
+target
+nbactions.xml
.settings
Copied: incubator/rave/trunk/rave-commons/src/main/java/org/apache/rave/exception/DuplicateItemException.java (from r1158276, incubator/rave/trunk/rave-commons/src/main/java/org/apache/rave/exception/NotSupportedException.java)
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-commons/src/main/java/org/apache/rave/exception/DuplicateItemException.java?p2=incubator/rave/trunk/rave-commons/src/main/java/org/apache/rave/exception/DuplicateItemException.java&p1=incubator/rave/trunk/rave-commons/src/main/java/org/apache/rave/exception/NotSupportedException.java&r1=1158276&r2=1158852&rev=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-commons/src/main/java/org/apache/rave/exception/NotSupportedException.java (original)
+++ incubator/rave/trunk/rave-commons/src/main/java/org/apache/rave/exception/DuplicateItemException.java Wed Aug 17 18:07:09 2011
@@ -19,22 +19,21 @@
package org.apache.rave.exception;
+import org.springframework.dao.DataAccessException;
+
/**
- *
+ * Runtime Exception Thrown when a duplicate item is attempted persistence
+ * (such as a unique constraint violation)
+ *
+ * @author carlucci
*/
-public class NotSupportedException extends RuntimeException{
- public NotSupportedException() {
- }
+public class DuplicateItemException extends DataAccessException {
- public NotSupportedException(String s) {
- super(s);
+ public DuplicateItemException(String msg, Throwable cause) {
+ super(msg, cause);
}
- public NotSupportedException(String s, Throwable throwable) {
- super(s, throwable);
- }
-
- public NotSupportedException(Throwable throwable) {
- super(throwable);
- }
+ public DuplicateItemException(String msg) {
+ super(msg);
+ }
}
Copied: incubator/rave/trunk/rave-commons/src/test/java/org/apache/rave/exception/DuplicateItemExceptionTest.java (from r1158818, incubator/rave/trunk/rave-commons/src/test/java/org/apache/rave/exception/NotSupportedExceptionTest.java)
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-commons/src/test/java/org/apache/rave/exception/DuplicateItemExceptionTest.java?p2=incubator/rave/trunk/rave-commons/src/test/java/org/apache/rave/exception/DuplicateItemExceptionTest.java&p1=incubator/rave/trunk/rave-commons/src/test/java/org/apache/rave/exception/NotSupportedExceptionTest.java&r1=1158818&r2=1158852&rev=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-commons/src/test/java/org/apache/rave/exception/NotSupportedExceptionTest.java (original)
+++ incubator/rave/trunk/rave-commons/src/test/java/org/apache/rave/exception/DuplicateItemExceptionTest.java Wed Aug 17 18:07:09 2011
@@ -26,23 +26,15 @@ import static org.junit.Assert.assertTha
/**
*/
-public class NotSupportedExceptionTest {
+public class DuplicateItemExceptionTest {
private static final String MESSAGE = "MESSAGE";
-
- @Test
- public void defaultConstructor() {
- try {
- throw new NotSupportedException();
- } catch (NotSupportedException e) {
- assertThat(e.getMessage(), is(nullValue()));
- }
- }
+
@Test
public void stringConstructor() {
try {
- throw new NotSupportedException(MESSAGE);
- } catch (NotSupportedException e) {
+ throw new DuplicateItemException(MESSAGE);
+ } catch (DuplicateItemException e) {
assertThat(e.getMessage(), is(equalTo(MESSAGE)));
}
}
@@ -50,20 +42,10 @@ public class NotSupportedExceptionTest {
public void stringAndCauseConstructor() {
Throwable throwable = new RuntimeException();
try {
- throw new NotSupportedException(MESSAGE, throwable);
- } catch (NotSupportedException e) {
- assertThat(e.getMessage(), is(equalTo(MESSAGE)));
- assertThat(e.getCause(), is(sameInstance(throwable)));
- }
- }
- @Test
- public void causeConstructor() {
- Throwable throwable = new RuntimeException(MESSAGE);
- try {
- throw new NotSupportedException(throwable);
- } catch (NotSupportedException e) {
- assertThat(e.getMessage(), is(equalTo(throwable.getClass().getCanonicalName() + ": " + MESSAGE)));
+ throw new DuplicateItemException(MESSAGE, throwable);
+ } catch (DuplicateItemException e) {
+ assertThat(e.getMessage(), is(equalTo(MESSAGE + "; nested exception is java.lang.RuntimeException")));
assertThat(e.getCause(), is(sameInstance(throwable)));
}
- }
+ }
}
Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/Page.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/Page.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/Page.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/Page.java Wed Aug 17 18:07:09 2011
@@ -30,7 +30,7 @@ import java.util.List;
* become more flexible to enable things like group ownership in the future).
*/
@Entity
-@Table(name="page")
+@Table(name="page", uniqueConstraints=@UniqueConstraint(columnNames={"owner_id","name"}))
@SequenceGenerator(name="pageIdSeq", sequenceName = "page_id_seq")
@NamedQueries({
@NamedQuery(name = "Page.getByUserId", query="SELECT p FROM Page p WHERE p.owner.id = :userId")
@@ -38,19 +38,19 @@ import java.util.List;
@Access(AccessType.FIELD)
public class Page implements BasicEntity, Serializable {
private static final long serialVersionUID = 1L;
-
+
@Id @Column(name="id")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "pageIdSeq")
private Long id;
- @Basic @Column(name="name")
+ @Basic(optional=false) @Column(name="name")
private String name;
@ManyToOne
@JoinColumn(name = "owner_id")
private User owner;
- @Basic @Column(name="render_sequence")
+ @Basic(optional=false) @Column(name="render_sequence")
private Long renderSequence;
@ManyToOne
Added: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/repository/impl/H2OpenJpaDialect.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/repository/impl/H2OpenJpaDialect.java?rev=1158852&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/repository/impl/H2OpenJpaDialect.java (added)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/repository/impl/H2OpenJpaDialect.java Wed Aug 17 18:07:09 2011
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rave.portal.repository.impl;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.rave.exception.DuplicateItemException;
+import org.h2.constant.ErrorCode;
+import org.h2.jdbc.JdbcSQLException;
+import org.springframework.dao.DataAccessException;
+import org.springframework.orm.jpa.vendor.OpenJpaDialect;
+
+/**
+ * This class is an extension of the OpenJpaDialect class used in configuring
+ * the EntityManagerFactory for our JPA layer. We needed to override the
+ * translateExceptionIfPossible method to map the H2 specific database errors
+ * to Rave's application exceptions. If/when a new Database provider is used instead
+ * of H2 a new class will need to be created for that database implementation.
+ *
+ *
+ * @author CARLUCCI
+ */
+public class H2OpenJpaDialect extends OpenJpaDialect {
+ /**
+ * Translates an H2 database error into a Rave application Exception
+ *
+ * @param re the RuntimeException to translate to a Rave application exception
+ * @return a Rave application exception representing the database error
+ */
+ @Override
+ public DataAccessException translateExceptionIfPossible(RuntimeException re) {
+ DataAccessException e = null;
+ // first make sure the root exception is actually an org.h2.jdbc.JdbcSQLException
+ if (ExceptionUtils.getRootCause(re) instanceof JdbcSQLException) {
+ JdbcSQLException rootException = (JdbcSQLException)ExceptionUtils.getRootCause(re);
+
+ // now translate the H2 specific error codes into Rave's common application Exceptions
+ // add more error codes to the switch statement that should be specifically trapped
+ switch(rootException.getErrorCode()) {
+ case ErrorCode.DUPLICATE_KEY_1: {
+ e = new DuplicateItemException("DUPLICATE_ITEM", rootException);
+ break;
+ }
+
+ default: {
+ e = new TranslatedH2Exception(rootException.getErrorCode(), "ERROR", "Unknown Database Error");
+ break;
+ }
+ }
+ } else {
+ // we got a RuntimeException that wasn't an org.h2.jdbc.JdbcSQLException
+ e = new TranslatedH2Exception(TranslatedH2Exception.UNKNOWN_ERROR_CODE, "ERROR", "Unknown Runtime Exception");
+ }
+
+ return e;
+ }
+}
\ No newline at end of file
Added: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/repository/impl/TranslatedH2Exception.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/repository/impl/TranslatedH2Exception.java?rev=1158852&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/repository/impl/TranslatedH2Exception.java (added)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/repository/impl/TranslatedH2Exception.java Wed Aug 17 18:07:09 2011
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rave.portal.repository.impl;
+
+import org.springframework.dao.DataAccessException;
+
+/**
+ * Exception class that represents an H2 database exception translated via Spring
+ *
+ * @author ACARLUCCI
+ */
+public class TranslatedH2Exception extends DataAccessException {
+ private int errorCode;
+ private String error;
+
+ public static final int UNKNOWN_ERROR_CODE = -1;
+
+ public TranslatedH2Exception(int errorCode, String error, String message) {
+ super(message);
+ this.errorCode = errorCode;
+ this.error = error;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ public String getError() {
+ return error;
+ }
+}
Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/PageService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/PageService.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/PageService.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/PageService.java Wed Aug 17 18:07:09 2011
@@ -23,6 +23,7 @@ import org.apache.rave.portal.model.Regi
import org.apache.rave.portal.model.RegionWidget;
import java.util.List;
+import org.apache.rave.portal.model.User;
public interface PageService {
/**
@@ -32,7 +33,34 @@ public interface PageService {
* @return A non null possible empty list of pages for the given user.
*/
List<Page> getAllPages(long userId);
-
+
+ /**
+ * Creates a new page with the supplied pageName and pageLayoutCode
+ *
+ * @param pageName the name of the new page
+ * @param pageLayoutCode the page layout code
+ * @return the new Page object
+ */
+ Page addNewPage(String pageName, String pageLayoutCode);
+
+ /**
+ * Creates a new default page for the supplied user using the
+ * supplied pageLayoutCode. This method should be used for new users
+ * who just registered and need to create the default page
+ *
+ * @param user
+ * @param pageLayoutCode
+ * @return
+ */
+ Page addNewDefaultPage(User user, String pageLayoutCode);
+
+ /**
+ * Get the default page name used by Rave
+ *
+ * @return the name of the default page used by Rave
+ */
+ String getDefaultPageName();
+
/**
* Moves a Region widget's position in a region or across regions
*
@@ -52,17 +80,11 @@ public interface PageService {
*/
RegionWidget addWidgetToPage(long page_id, long widget_id);
- /**
- * Deletes the specified widget from the page.
- *
- * @param regionWidgetId the id of the region widget to delete.\
- * @return the region from which the widget was deleted
- */
- Region removeWidgetFromPage(long regionWidgetId);
-
- /**
- * Registers a new page.
- * @param page the page object to register with the data management system.
- */
- void registerNewPage(Page page);
+ /**
+ * Deletes the specified widget from the page.
+ *
+ * @param regionWidgetId the id of the region widget to delete.\
+ * @return the region from which the widget was deleted
+ */
+ Region removeWidgetFromPage(long regionWidgetId);
}
\ No newline at end of file
Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultNewAccountService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultNewAccountService.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultNewAccountService.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultNewAccountService.java Wed Aug 17 18:07:09 2011
@@ -41,71 +41,48 @@ import org.springframework.stereotype.Se
@Service
public class DefaultNewAccountService implements NewAccountService {
- protected final Logger logger=LoggerFactory.getLogger(getClass());
+ protected final Logger logger=LoggerFactory.getLogger(getClass());
private final UserService userService;
- private final PageService pageService;
- private final PageLayoutService pageLayoutService;
- private final RegionService regionService;
+ private final PageService pageService;
+ private final PageLayoutService pageLayoutService;
+ private final RegionService regionService;
+ @Autowired
+ private SaltSource saltSource;
- @Autowired
- private SaltSource saltSource;
-
- @Autowired
- private PasswordEncoder passwordEncoder;
+ @Autowired
+ private PasswordEncoder passwordEncoder;
@Autowired
public DefaultNewAccountService(UserService userService, PageService pageService, PageLayoutService pageLayoutService, RegionService regionService) {
- this.userService = userService;
- this.pageService = pageService;
- this.pageLayoutService = pageLayoutService;
- this.regionService = regionService;
+ this.userService = userService;
+ this.pageService = pageService;
+ this.pageLayoutService = pageLayoutService;
+ this.regionService = regionService;
}
- @Override
- public void createNewAccount(String userName, String password, String userPageLayout) throws Exception {
- final User existingUser = userService.getUserByUsername(userName);
- if (existingUser != null) {
+ @Override
+ public void createNewAccount(String userName, String password, String userPageLayout) throws Exception {
+ final User existingUser = userService.getUserByUsername(userName);
+ if (existingUser != null) {
throw new IllegalArgumentException("A user already exists for username " + userName);
- }
-
- User user=new User();
- user.setUsername(userName);
- //This assumes we use the username for the salt. If not, the code below will need to change.
- //See also applicationContext-security.xml
- String saltedHashedPassword=passwordEncoder.encodePassword(password,saltSource.getSalt(user));
+ }
+
+ User user=new User();
+ user.setUsername(userName);
+ //This assumes we use the username for the salt. If not, the code below will need to change.
+ //See also applicationContext-security.xml
+ String saltedHashedPassword=passwordEncoder.encodePassword(password,saltSource.getSalt(user));
logger.debug("Salt Source: {}", saltSource.getSalt(user));
- user.setPassword(saltedHashedPassword);
-
- user.setExpired(false);
- user.setLocked(false);
- user.setEnabled(true);
- userService.registerNewUser(user);
-
- //Return the newly registered user
- User registeredUser=userService.getUserByUsername(user.getUsername());
-
- //Create a PageLayout object.
- PageLayout pageLayout=pageLayoutService.getPageLayoutByCode(userPageLayout);
-
- //Create regions
- List<Region> regions=new ArrayList<Region>();
- int regionCount;
- for (regionCount = 0; regionCount < pageLayout.getNumberOfRegions(); regionCount++) {
- Region region = new Region();
- regions.add(region);
- }
-
- //Create a Page object and register it.
- Page page=new Page();
- page.setName("main");
- page.setOwner(registeredUser);
- page.setPageLayout(pageLayout);
- page.setRenderSequence(1L);
- page.setRegions(regions);
- pageService.registerNewPage(page);
-
- }
-
+ user.setPassword(saltedHashedPassword);
+
+ user.setExpired(false);
+ user.setLocked(false);
+ user.setEnabled(true);
+ userService.registerNewUser(user);
+
+ // Return the newly registered user and create a new default page for them
+ pageService.addNewDefaultPage(userService.getUserByUsername(user.getUsername()), userPageLayout);
+ }
}
\ No newline at end of file
Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java Wed Aug 17 18:07:09 2011
@@ -19,6 +19,7 @@
package org.apache.rave.portal.service.impl;
+import java.util.ArrayList;
import org.apache.rave.persistence.Repository;
import org.apache.rave.portal.model.Page;
import org.apache.rave.portal.model.Region;
@@ -34,6 +35,11 @@ import org.springframework.stereotype.Se
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
+import org.apache.rave.portal.model.PageLayout;
+import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.repository.PageLayoutRepository;
+import org.apache.rave.portal.service.UserService;
+import org.springframework.beans.factory.annotation.Value;
@Service
public class DefaultPageService implements PageService {
@@ -41,19 +47,48 @@ public class DefaultPageService implemen
private final RegionRepository regionRepository;
private final RegionWidgetRepository regionWidgetRepository;
private final WidgetRepository widgetRepository;
+ private final PageLayoutRepository pageLayoutRepository;
+ private final UserService userService;
+ private final String defaultPageName;
@Autowired
- public DefaultPageService(PageRepository pageRepository, RegionRepository regionRepository, WidgetRepository widgetRepository, RegionWidgetRepository regionWidgetRepository) {
+ public DefaultPageService(PageRepository pageRepository,
+ RegionRepository regionRepository,
+ WidgetRepository widgetRepository,
+ RegionWidgetRepository regionWidgetRepository,
+ PageLayoutRepository pageLayoutRepository,
+ UserService userService,
+ @Value("${portal.page.default_name}") String defaultPageName) {
this.pageRepository = pageRepository;
this.regionRepository = regionRepository;
this.regionWidgetRepository = regionWidgetRepository;
this.widgetRepository = widgetRepository;
+ this.pageLayoutRepository = pageLayoutRepository;
+ this.userService = userService;
+ this.defaultPageName = defaultPageName;
}
@Override
public List<Page> getAllPages(long userId) {
return pageRepository.getAllPages(userId);
}
+
+ @Override
+ @Transactional
+ public Page addNewPage(String pageName, String pageLayoutCode) {
+ return addNewPage(userService.getAuthenticatedUser(), pageName, pageLayoutCode);
+ }
+
+ @Override
+ @Transactional
+ public Page addNewDefaultPage(User user, String pageLayoutCode) {
+ return addNewPage(user, defaultPageName, pageLayoutCode);
+ }
+
+ @Override
+ public String getDefaultPageName() {
+ return defaultPageName;
+ }
@Override
@Transactional
@@ -85,12 +120,6 @@ public class DefaultPageService implemen
return createWidgetInstance(widget, region, 0);
}
- @Override
- @Transactional
- public void registerNewPage(Page page) {
- pageRepository.save(page);
- }
-
private RegionWidget createWidgetInstance(Widget widget, Region region, int position) {
RegionWidget regionWidget = new RegionWidget();
regionWidget.setRenderOrder(position);
@@ -145,4 +174,27 @@ public class DefaultPageService implemen
throw new IllegalArgumentException("Invalid RegionWidget ID");
}
+ private Page addNewPage(User user, String pageName, String pageLayoutCode) {
+ PageLayout pageLayout = pageLayoutRepository.getByPageLayoutCode(pageLayoutCode);
+
+ // Create regions
+ List<Region> regions = new ArrayList<Region>();
+ int regionCount;
+ for (regionCount = 0; regionCount < pageLayout.getNumberOfRegions(); regionCount++) {
+ Region region = new Region();
+ regions.add(region);
+ }
+
+ // Create a Page object and register it.
+ long renderSequence = getAllPages(user.getId()).size() + 1;
+ Page page = new Page();
+ page.setName(pageName);
+ page.setOwner(user);
+ page.setPageLayout(pageLayout);
+ page.setRenderSequence(renderSequence);
+ page.setRegions(regions);
+ pageRepository.save(page);
+
+ return page;
+ }
}
\ No newline at end of file
Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java Wed Aug 17 18:07:09 2011
@@ -16,9 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.apache.rave.portal.web.api.rpc;
+import org.apache.rave.portal.model.Page;
import org.apache.rave.portal.model.Region;
import org.apache.rave.portal.model.RegionWidget;
import org.apache.rave.portal.service.PageService;
@@ -35,95 +35,106 @@ import org.springframework.web.bind.anno
@RequestMapping(value = "/api/rpc/page/*")
public class PageApi {
- private final PageService pageService;
+ private final PageService pageService;
- @Autowired
- public PageApi(PageService pageService) {
- this.pageService = pageService;
- }
-
- /**
- * Adds a widget to the given page
- *
- * @param pageId
- * the ID of the {@link org.apache.rave.portal.model.Page} to add
- * the widget to
- * @param widgetId
- * the ID of the {@link org.apache.rave.portal.model.Widget} to
- * add do the page
- * @return a {@link RpcOperation} containing the new widget instance (
- * {@link org.apache.rave.portal.model.RegionWidget }) or any errors
- * encountered while performing the RPC operation
- */
- @ResponseBody
- @RequestMapping(method = RequestMethod.POST, value = "{pageId}/widget/add")
- public RpcResult<RegionWidget> addWidgetToPage(
- @PathVariable final long pageId, @RequestParam final long widgetId) {
-
- return new RpcOperation<RegionWidget>() {
- @Override
- public RegionWidget execute() {
- return pageService.addWidgetToPage(pageId, widgetId);
- }
- }.getResult();
- }
-
- /**
- * Moves a widget to a new location
- * <p/>
- * Moves can take place within a region, region to region, or between pages
- *
- * @param regionWidgetId
- * the ID of the
- * {@link org.apache.rave.portal.model.RegionWidget} to move
- * @param newPosition
- * the 0 based index within the region where the RegionWidget
- * will now be located
- * @param toRegion
- * the Id of the {@link org.apache.rave.portal.model.Region }
- * where the widget will now be located
- * @param fromRegion
- * the Id of the {@link org.apache.rave.portal.model.Region }
- * where the widget is currently located
- * @return a {@link RpcOperation} containing the updated widget instance (
- * {@link org.apache.rave.portal.model.RegionWidget }) or any errors
- * encountered while performing the RPC operation
- */
- @ResponseBody
- @RequestMapping(method = RequestMethod.POST, value = "regionWidget/{regionWidgetId}/move")
- public RpcResult<RegionWidget> moveWidgetOnPage(
- @PathVariable final long regionWidgetId,
- @RequestParam final int newPosition,
- @RequestParam final long toRegion,
- @RequestParam final long fromRegion) {
-
- return new RpcOperation<RegionWidget>() {
- @Override
- public RegionWidget execute() {
- return pageService.moveRegionWidget(regionWidgetId,
- newPosition, toRegion, fromRegion);
- }
- }.getResult();
- }
-
- /**
- * Deletes a widget
- *
- * @param regionWidgetId
- * the ID of the {@link org.apache.rave.portal.model.Widget} to
- * delete
- * @return an {@link RpcOperation} containing the updated region or any
- * errors encountered.
- */
- @ResponseBody
- @RequestMapping(method=RequestMethod.POST, value="regionWidget/{regionWidgetId}/delete")
- public RpcResult<Region> removeWidgetFromPage(@PathVariable final long regionWidgetId) {
- return new RpcOperation<Region>() {
- @Override
- public Region execute() {
- return pageService.removeWidgetFromPage(regionWidgetId);
+ @Autowired
+ public PageApi(PageService pageService) {
+ this.pageService = pageService;
+ }
+
+ /**
+ * Adds a widget to the given page
+ *
+ * @param pageId
+ * the ID of the {@link org.apache.rave.portal.model.Page} to add
+ * the widget to
+ * @param widgetId
+ * the ID of the {@link org.apache.rave.portal.model.Widget} to
+ * add do the page
+ * @return a {@link RpcOperation} containing the new widget instance (
+ * {@link org.apache.rave.portal.model.RegionWidget }) or any errors
+ * encountered while performing the RPC operation
+ */
+ @ResponseBody
+ @RequestMapping(method = RequestMethod.POST, value = "{pageId}/widget/add")
+ public RpcResult<RegionWidget> addWidgetToPage(
+ @PathVariable final long pageId, @RequestParam final long widgetId) {
+
+ return new RpcOperation<RegionWidget>() {
+ @Override
+ public RegionWidget execute() {
+ return pageService.addWidgetToPage(pageId, widgetId);
}
- }.getResult();
+ }.getResult();
}
+ /**
+ * Moves a widget to a new location
+ * <p/>
+ * Moves can take place within a region, region to region, or between pages
+ *
+ * @param regionWidgetId
+ * the ID of the
+ * {@link org.apache.rave.portal.model.RegionWidget} to move
+ * @param newPosition
+ * the 0 based index within the region where the RegionWidget
+ * will now be located
+ * @param toRegion
+ * the Id of the {@link org.apache.rave.portal.model.Region }
+ * where the widget will now be located
+ * @param fromRegion
+ * the Id of the {@link org.apache.rave.portal.model.Region }
+ * where the widget is currently located
+ * @return a {@link RpcOperation} containing the updated widget instance (
+ * {@link org.apache.rave.portal.model.RegionWidget }) or any errors
+ * encountered while performing the RPC operation
+ */
+ @ResponseBody
+ @RequestMapping(method = RequestMethod.POST, value = "regionWidget/{regionWidgetId}/move")
+ public RpcResult<RegionWidget> moveWidgetOnPage(
+ @PathVariable final long regionWidgetId,
+ @RequestParam final int newPosition,
+ @RequestParam final long toRegion,
+ @RequestParam final long fromRegion) {
+
+ return new RpcOperation<RegionWidget>() {
+ @Override
+ public RegionWidget execute() {
+ return pageService.moveRegionWidget(regionWidgetId,
+ newPosition, toRegion, fromRegion);
+ }
+ }.getResult();
+ }
+
+ /**
+ * Deletes a widget
+ *
+ * @param regionWidgetId
+ * the ID of the {@link org.apache.rave.portal.model.Widget} to
+ * delete
+ * @return an {@link RpcOperation} containing the updated region or any
+ * errors encountered.
+ */
+ @ResponseBody
+ @RequestMapping(method = RequestMethod.POST, value = "regionWidget/{regionWidgetId}/delete")
+ public RpcResult<Region> removeWidgetFromPage(@PathVariable final long regionWidgetId) {
+ return new RpcOperation<Region>() {
+ @Override
+ public Region execute() {
+ return pageService.removeWidgetFromPage(regionWidgetId);
+ }
+ }.getResult();
+ }
+
+ @ResponseBody
+ @RequestMapping(method = RequestMethod.POST, value = "add")
+ public RpcResult<Page> addPage(@RequestParam final String pageName,
+ @RequestParam final String pageLayoutCode) {
+ return new RpcOperation<Page>() {
+ @Override
+ public Page execute() {
+ return pageService.addNewPage(pageName, pageLayoutCode);
+ }
+ }.getResult();
+ }
}
Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/model/RpcOperation.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/model/RpcOperation.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/model/RpcOperation.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/model/RpcOperation.java Wed Aug 17 18:07:09 2011
@@ -19,6 +19,8 @@
package org.apache.rave.portal.web.api.rpc.model;
+import org.apache.rave.exception.DuplicateItemException;
+
/**
* Defines an RPC operation that can be executed to return a given result
*/
@@ -36,9 +38,11 @@ public abstract class RpcOperation<T> {
T subject = execute();
result = new RpcResult<T>(false, subject);
} catch (IllegalArgumentException e) {
- result = new RpcResult<T>(true, e.getMessage(), RpcResult.ErrorCode.INVALID_PARAMS);
+ result = createRpcResultError(e, RpcResult.ErrorCode.INVALID_PARAMS);
+ } catch (DuplicateItemException e) {
+ result = createRpcResultError(e, RpcResult.ErrorCode.DUPLICATE_ITEM);
} catch (Exception e) {
- result = new RpcResult<T>(true, e.getMessage(), RpcResult.ErrorCode.INTERNAL_ERROR);
+ result = createRpcResultError(e, RpcResult.ErrorCode.INTERNAL_ERROR);
}
return result;
}
@@ -49,4 +53,8 @@ public abstract class RpcOperation<T> {
* @return the result of the RPC operation
*/
public abstract T execute();
-}
+
+ private RpcResult<T> createRpcResultError(Exception e, RpcResult.ErrorCode errorCode) {
+ return new RpcResult<T>(true, e.getMessage(), errorCode);
+ }
+}
\ No newline at end of file
Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/model/RpcResult.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/model/RpcResult.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/model/RpcResult.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/model/RpcResult.java Wed Aug 17 18:07:09 2011
@@ -30,7 +30,8 @@ public class RpcResult<T> {
public static enum ErrorCode {
NO_ERROR,
INVALID_PARAMS,
- INTERNAL_ERROR
+ INTERNAL_ERROR,
+ DUPLICATE_ITEM
}
private boolean error;
Modified: incubator/rave/trunk/rave-portal/src/main/resources/portal.properties
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/resources/portal.properties?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/resources/portal.properties (original)
+++ incubator/rave/trunk/rave-portal/src/main/resources/portal.properties Wed Aug 17 18:07:09 2011
@@ -28,4 +28,7 @@ portal.opensocial_engine.gadget_path=/ga
portal.opensocial_security.encryptionkey=classpath:security_token_encryption_key.txt
portal.opensocial_security.container=default
-portal.opensocial_security.domain=default
\ No newline at end of file
+portal.opensocial_security.domain=default
+
+# the default page name to create for new users
+portal.page.default_name=Main
\ No newline at end of file
Modified: incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/applicationContext.xml
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/applicationContext.xml?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/applicationContext.xml (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/applicationContext.xml Wed Aug 17 18:07:09 2011
@@ -68,10 +68,14 @@
<property name="persistenceUnitName" value="ravePersistenceUnit"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
- <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
- <property name="showSql" value="true" />
- </bean>
+ <bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"
+ p:databasePlatform="org.apache.openjpa.jdbc.sql.H2Dictionary"
+ p:database="H2"
+ p:showSql="true"/>
</property>
+ <property name="jpaDialect">
+ <bean class="org.apache.rave.portal.repository.impl.H2OpenJpaDialect"/>
+ </property>
<property name="jpaPropertyMap">
<map>
<entry key="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
@@ -80,7 +84,7 @@
</map>
</property>
</bean>
-
+
<!-- A RestTemplate instance that can be used to call a web service which expects Content-Type and Accept headers of
application/json with a pre-built string of JSON data. -->
<bean id="jsonStringCompatibleRestTemplate" class="org.springframework.web.client.RestTemplate">
@@ -104,17 +108,17 @@
<property name="engineGadgetPath" value="${portal.opensocial_engine.gadget_path}"/>
</bean>
- <!-- Validators -->
- <bean id="newAccountValidator" class="org.apache.rave.portal.web.validator.NewAccountValidator"/>
- <bean id="userProfileValidator" class="org.apache.rave.portal.web.validator.UserProfileValidator"/>
+ <!-- Validators -->
+ <bean id="newAccountValidator" class="org.apache.rave.portal.web.validator.NewAccountValidator"/>
+ <bean id="userProfileValidator" class="org.apache.rave.portal.web.validator.UserProfileValidator"/>
- <!-- Configuring messages.properties file -->
- <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource" p:basename="messages" />
+ <!-- Configuring messages.properties file -->
+ <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource" p:basename="messages" />
- <!-- Password encoding and salting-->
- <bean class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" id="passwordEncoder"/>
- <bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
- <property name="userPropertyToUse" value="username"/>
- </bean>
+ <!-- Password encoding and salting-->
+ <bean class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" id="passwordEncoder"/>
+ <bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
+ <property name="userPropertyToUse" value="username"/>
+ </bean>
</beans>
\ No newline at end of file
Modified: incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp Wed Aug 17 18:07:09 2011
@@ -40,25 +40,26 @@
<h1>Hello ${defaultPage.owner.username}, welcome to Rave!</h1>
</div>
<div id="dialog" title="Tab data" class="dialog">
- <form>
- <fieldset class="ui-helper-reset">
- <label for="tab_title">Title</label>
- <input type="text" name="tab_title" id="tab_title" value="" class="ui-widget-content ui-corner-all" />
- <label for="pageLayoutField">Select Page Layout:</label>
- <select>
- <option value="columns_1" id="columns_1_id">One Column</option>
- <option value="columns_2" id="columns_2_id" selected="selected">Two Columns</option>
- <option value="columns_2wn" id="columns_2wn_id">Two Columns (wide/narrow)</option>
- <option value="columns_3" id="columns_3_id">Three Columns</option>
- <option value="columns_3nwn" id="columns_3nwn_id">Three Columns (narrow/wide/narrow)</option>
- <option value="columns_4" id="columns_4_id">Four Columns</option>
- <option value="columns_3nwn_1_bottom" id="columns_3nwn_1_bottom">Four Columns (narrow/wide/narrow/bottom)</option>
- </select>
- </fieldset>
- </form>
- </div>
- <button id="add_tab">Add Tab</button>
- <div id="tabs" class="rave-ui-tabs">
+ <form id="pageForm">
+ <div id="pageFormErrors" class="error"></div>
+ <fieldset class="ui-helper-reset">
+ <label for="tab_title">Title</label>
+ <input type="text" name="tab_title" id="tab_title" value="" class="required ui-widget-content ui-corner-all" />
+ <label for="pageLayoutField">Select Page Layout:</label>
+ <select name="pageLayout" id="pageLayout">
+ <option value="columns_1" id="columns_1_id">One Column</option>
+ <option value="columns_2" id="columns_2_id" selected="selected">Two Columns</option>
+ <option value="columns_2wn" id="columns_2wn_id">Two Columns (wide/narrow)</option>
+ <option value="columns_3" id="columns_3_id">Three Columns</option>
+ <option value="columns_3nwn" id="columns_3nwn_id">Three Columns (narrow/wide/narrow)</option>
+ <option value="columns_4" id="columns_4_id">Four Columns</option>
+ <option value="columns_3nwn_1_bottom" id="columns_3nwn_1_bottom">Four Columns (narrow/wide/narrow/bottom)</option>
+ </select>
+ </fieldset>
+ </form>
+ </div>
+ <button id="add_tab">Add Tab</button>
+ <div id="tabs" class="rave-ui-tabs">
<ul class="rave-ui-tabs ui-tabs-nav">
<c:forEach var="page" items="${pages}">
<li>
@@ -102,6 +103,7 @@
<script src="//cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.ui/1.8.13/jquery-ui.min.js"></script>
+ <script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.8.1/jquery.validate.min.js"></script>
<script src="${opensocial_engine_url}/js/container.js?c=1&container=default&debug=1"></script>
<script src="<spring:url value="/script/rave.js"/>"></script>
<script src="<spring:url value="/script/rave_api.js"/>"></script>
@@ -132,5 +134,8 @@
$(function() {
$( "#tabs" ).tabs();
});
+
+ // initialize the page form validator
+ rave.forms.validateUserProfileForm();
</script>
</rave:rave_generic_page>
Modified: incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_api.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_api.js?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_api.js (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_api.js Wed Aug 17 18:07:09 2011
@@ -130,6 +130,28 @@ rave.api = rave.api || (function() {
}
}).error(handleError);
}
+
+ function addPage(args) {
+ $.post(rave.getContext() + path + "page/add",
+ {
+ pageName: args.pageName,
+ pageLayoutCode: args.pageLayoutCode
+ },
+ function(result) {
+ if (result.error) {
+ // check to see if a duplicate page name error occured
+ if (result.errorCode == 'DUPLICATE_ITEM') {
+ $("#pageFormErrors").html("A page with that name already exists");
+ } else {
+ handleRpcError(result);
+ }
+ } else {
+ if (typeof args.successCallback == 'function') {
+ args.successCallback();
+ }
+ }
+ }).error(handleError);
+ }
//TODO: Create a more robust error handling system and interrogation of RPC results
function handleRpcError(rpcResult) {
@@ -143,14 +165,15 @@ rave.api = rave.api || (function() {
case "INTERNAL_ERROR":
alert("Rave attempted to update the server with your recent changes, " +
" but the server encountered an internal error.");
- break;
+ break;
}
}
return {
moveWidget : moveWidgetOnPage,
addWidgetToPage : addWidgetToPage,
- removeWidget : deleteWidgetOnPage
+ removeWidget : deleteWidgetOnPage,
+ addPage: addPage
};
})();
Modified: incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_forms.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_forms.js?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_forms.js (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_forms.js Wed Aug 17 18:07:09 2011
@@ -65,9 +65,20 @@ rave.forms = rave.forms || (function() {
}
});
}
+
+ function validatePageForm() {
+ $("#pageForm").validate({
+ rules: {
+ tab_title : {
+ required: true
+ }
+ }
+ });
+ }
return {
validateNewAccountForm : validateNewAccountForm,
- validateUserProfileForm: validateUserProfileForm
+ validateUserProfileForm: validateUserProfileForm,
+ validatePageForm: validatePageForm
};
})();
Modified: incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_layout.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_layout.js?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_layout.js (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_layout.js Wed Aug 17 18:07:09 2011
@@ -17,64 +17,79 @@
* under the License.
*/
$(function() {
- var $tab_title_input = $( "#tab_title"),
- $tab_content_input = $( "#tab_content" );
- var tab_counter = 2;
- // tabs init with a custom tab template and an "add" callback filling in the content
- var $tabs = $( "#tabs").tabs({
- tabTemplate: "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
- add: function( event, ui ) {
- var tab_content = $tab_content_input.val() || "Tab " + tab_counter + " content.";
- $( ui.panel ).append( "<p>" + tab_content + "</p>" );
- }
- });
-
- // modal dialog init: custom buttons and a "close" callback reseting the form inside
- var $dialog = $( "#dialog" ).dialog({
- autoOpen: false,
- modal: true,
- buttons: {
- Add: function() {
- addTab();
- $( this ).dialog( "close" );
- },
- Cancel: function() {
- $( this ).dialog( "close" );
- }
- },
- open: function() {
- $tab_title_input.focus();
- },
- close: function() {
- $form[ 0 ].reset();
- }
- });
-
- // addTab form: calls addTab function on submit and closes the dialog
- var $form = $( "form", $dialog ).submit(function() {
- addTab();
- $dialog.dialog( "close" );
- return false;
- });
-
- // actual addTab function: adds new tab using the title input from the form above
- function addTab() {
- var tab_title = $tab_title_input.val() || "Tab " + tab_counter;
- $tabs.tabs( "add", "#tabs-" + tab_counter, tab_title );
- tab_counter++;
- }
-
- // addTab button: just opens the dialog
- $( "#add_tab" )
- .button()
- .click(function() {
- $dialog.dialog( "open" );
- });
-
- // close icon: removing the tab on click
- // note: closable tabs gonna be an option in the future - see http://dev.jqueryui.com/ticket/3924
- $( "#tabs span.ui-icon-close" ).live( "click", function() {
- var index = $( "li", $tabs ).index( $( this ).parent() );
- $tabs.tabs( "remove", index );
- });
+ var $tab_title_input = $( "#tab_title"),
+ $page_layout_input = $("#pageLayout"),
+ $tab_content_input = $( "#tab_content" );
+
+ var tab_counter = 2;
+ // tabs init with a custom tab template and an "add" callback filling in the content
+ var $tabs = $( "#tabs").tabs({
+ tabTemplate: "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ui-icon-close'>Remove Tab</span></li>",
+ add: function( event, ui ) {
+ var tab_content = $tab_content_input.val() || "Tab " + tab_counter + " content.";
+ $( ui.panel ).append( "<p>" + tab_content + "</p>" );
+ }
+ });
+
+ // modal dialog init: custom buttons and a "close" callback reseting the form inside
+ var $dialog = $( "#dialog" ).dialog({
+ autoOpen: false,
+ modal: true,
+ buttons: {
+ Add: function() {
+ addPage();
+ },
+ Cancel: function() {
+ $( this ).dialog( "close" );
+ }
+ },
+ open: function() {
+ $tab_title_input.focus();
+ },
+ close: function() {
+ $form[ 0 ].reset();
+ $("#pageFormErrors").html("");
+ }
+ });
+
+ // define the form object
+ var $form = $("#pageForm", $dialog);
+
+ function addPage() {
+ // if the form has passed validation submit the request
+ if ($("#pageForm").valid()) {
+ var newPageTitle = $tab_title_input.val();
+ var newPageLayoutCode = $page_layout_input.val();
+
+ // send the rpc request to create the new page
+ rave.api.rpc.addPage({pageName: newPageTitle,
+ pageLayoutCode: newPageLayoutCode,
+ successCallback: function() { addPageCallback(newPageTitle); }
+ });
+ }
+ }
+
+ function addPageCallback(newPageTitle) {
+ // add the new page tab to the list of pages
+ // TODO - in the future this should be changed to redirect to the new page after creating it
+ var pageTitle = newPageTitle;
+ $tabs.tabs("add", "#tabs-" + tab_counter, pageTitle);
+ tab_counter++;
+
+ $dialog.dialog( "close" );
+ }
+
+ // addTab button: just opens the dialog
+ $( "#add_tab" )
+ .button()
+ .click(function() {
+ $dialog.dialog( "open" );
+ });
+
+ // close icon: removing the tab on click
+ // note: closable tabs gonna be an option in the future - see http://dev.jqueryui.com/ticket/3924
+ $( "#tabs span.ui-icon-close" ).live( "click", function() {
+ var index = $( "li", $tabs ).index( $( this ).parent() );
+ $tabs.tabs( "remove", index );
+ });
});
\ No newline at end of file
Modified: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/AbstractJpaRepositoryTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/AbstractJpaRepositoryTest.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/AbstractJpaRepositoryTest.java (original)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/AbstractJpaRepositoryTest.java Wed Aug 17 18:07:09 2011
@@ -79,9 +79,10 @@ public class AbstractJpaRepositoryTest {
@Test
@Rollback(true)
- public void save_newEntity() {
+ public void save_newEntity() throws Exception {
for (Repository repository : repositories) {
- BasicEntity entity = constructNewEntityForRepository(repository);
+ BasicEntity entity = constructNewEntityForRepository(repository);
+ RepositoryTestUtils.populateAllRequiredFieldsInEntity(sharedManager, entity);
BasicEntity saved = (BasicEntity)repository.save(entity);
sharedManager.flush();
assertThat(saved, is(sameInstance(entity)));
@@ -121,5 +122,5 @@ public class AbstractJpaRepositoryTest {
throw new RuntimeException(e);
}
}
-
+
}
Added: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/RepositoryTestUtils.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/RepositoryTestUtils.java?rev=1158852&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/RepositoryTestUtils.java (added)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/RepositoryTestUtils.java Wed Aug 17 18:07:09 2011
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rave.portal.repository;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import javax.persistence.Entity;
+import javax.persistence.EntityManager;
+import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.persistence.JPAFacadeHelper;
+import org.apache.rave.persistence.BasicEntity;
+
+/**
+ *
+ * @author ACARLUCCI
+ */
+public class RepositoryTestUtils {
+
+ /**
+ * Utility function for populating all required fields in model entities
+ * by using reflection and JPA entity meta data inspection to determine
+ * which fields are NOT NULL allowable.
+ *
+ * @param entityManager
+ * @param entity
+ * @throws Exception
+ */
+ public static void populateAllRequiredFieldsInEntity(EntityManager entityManager, BasicEntity entity) throws Exception {
+ // loop over all fields in entity and determine which ones are
+ // "required", (optional=false) in JPA config terms, and set a value
+ // to those fields
+ FieldMetaData[] declaredFields = JPAFacadeHelper.getMetaData(entityManager, entity.getClass()).getDeclaredFields();
+ // for each field int the entity...
+ for (FieldMetaData fieldMetaData : declaredFields) {
+ // if the field is declared optional=false...
+ if (fieldMetaData.getFieldMetaData().getNullValue() == FieldMetaData.NULL_EXCEPTION) {
+ String fieldName = fieldMetaData.getName();
+ // using reflection obtain the getter and setter methods for this field...
+ for (Method method : entity.getClass().getDeclaredMethods()) {
+ String methodPrefix = method.getName().substring(0,3);
+ String methodName = method.getName().substring(3);
+ if("get".equals(methodPrefix) && fieldName.equalsIgnoreCase(methodName)) {
+ String setterMethodName = "set" + methodName;
+ Method setterMethod = entity.getClass().getMethod(setterMethodName, method.getReturnType());
+ invokeEntitySetterMethodBasedOnAvailableConstructor(entity, method, setterMethod);
+ }
+ }
+ }
+ }
+ }
+
+ private static void invokeEntitySetterMethodBasedOnAvailableConstructor(BasicEntity entity, Method getterMethod, Method setterMethod) throws Exception {
+ // first see if there is a simple no-arg default constructor for this field type
+ Constructor<?> defaultConstructor = null;
+ try {
+ defaultConstructor = getterMethod.getReturnType().getConstructor();
+ } catch (NoSuchMethodException e) { }
+
+ if (defaultConstructor != null) {
+ setterMethod.invoke(entity, defaultConstructor.newInstance());
+ } else {
+ // check to see what the type is and invoke a constructor
+ // new classes might need to be added here in the future
+ // based on what fields are required in the models
+ if (getterMethod.getReturnType().equals(Long.class)) {
+ setterMethod.invoke(entity, new Long(1L));
+ } else if (getterMethod.getReturnType().equals(Integer.class)) {
+ setterMethod.invoke(entity, new Integer(1));
+ }
+ }
+ }
+}
Added: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/impl/H2OpenJpaDialectTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/impl/H2OpenJpaDialectTest.java?rev=1158852&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/impl/H2OpenJpaDialectTest.java (added)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/impl/H2OpenJpaDialectTest.java Wed Aug 17 18:07:09 2011
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.rave.portal.repository.impl;
+
+import org.apache.rave.exception.DuplicateItemException;
+import org.h2.jdbc.JdbcSQLException;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import static org.hamcrest.CoreMatchers.*;
+import org.h2.constant.ErrorCode;
+import org.springframework.dao.DataAccessException;
+
+/**
+ *
+ * @author ACARLUCCI
+ */
+public class H2OpenJpaDialectTest {
+ private H2OpenJpaDialect dialect;
+
+ @Before
+ public void setUp() {
+ dialect = new H2OpenJpaDialect();
+ }
+
+ /**
+ * Test of translateExceptionIfPossible method, of class H2OpenJpaDialect.
+ */
+ @Test
+ public void testTranslateExceptionIfPossible_uniqueContstraintViolation() {
+ JdbcSQLException jdbcEx = new JdbcSQLException("message", "sql statement", "state", ErrorCode.DUPLICATE_KEY_1, null, "stacktrace");
+ RuntimeException re = new RuntimeException("dummy runtime exception", jdbcEx);
+
+ assertThat(dialect.translateExceptionIfPossible(re), is(DuplicateItemException.class));
+ }
+
+ @Test
+ public void testTranslateExceptionIfPossible_unknownJdbcSQLExceptionError() {
+ JdbcSQLException jdbcEx = new JdbcSQLException("message", "sql statement", "state", ErrorCode.CANNOT_DROP_CURRENT_USER, null, "stacktrace");
+ RuntimeException re = new RuntimeException("dummy runtime exception", jdbcEx);
+
+ TranslatedH2Exception translatedException = (TranslatedH2Exception) dialect.translateExceptionIfPossible(re);
+ assertThat(translatedException.getErrorCode(), is(ErrorCode.CANNOT_DROP_CURRENT_USER));
+ }
+
+ @Test
+ public void testTranslateExceptionIfPossible_unknownRuntimeError() {
+ RuntimeException re = new RuntimeException("dummy runtime exception", new NullPointerException("bad"));
+
+ TranslatedH2Exception translatedException = (TranslatedH2Exception) dialect.translateExceptionIfPossible(re);
+ assertThat(translatedException.getErrorCode(), is(TranslatedH2Exception.UNKNOWN_ERROR_CODE));
+ }
+}
Added: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/impl/TranslatedH2ExceptionTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/impl/TranslatedH2ExceptionTest.java?rev=1158852&view=auto
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/impl/TranslatedH2ExceptionTest.java (added)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/repository/impl/TranslatedH2ExceptionTest.java Wed Aug 17 18:07:09 2011
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.rave.portal.repository.impl;
+
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import static org.hamcrest.CoreMatchers.*;
+
+/**
+ *
+ * @author CARLUCCI
+ */
+public class TranslatedH2ExceptionTest {
+ private final int ERROR_CODE = 123;
+ private final String ERROR = "Dummy Error";
+ private final String MESSAGE = "H2 specific error message";
+
+ private TranslatedH2Exception e;
+
+ @Before
+ public void setup() {
+ e = new TranslatedH2Exception(ERROR_CODE, ERROR, MESSAGE);
+ }
+
+ /**
+ * Test of getErrorCode method, of class TranslatedH2Exception.
+ */
+ @Test
+ public void testGetErrorCode() {
+ assertThat(e.getErrorCode(), is(ERROR_CODE));
+ }
+
+ /**
+ * Test of getError method, of class TranslatedH2Exception.
+ */
+ @Test
+ public void testGetError() {
+ assertThat(e.getError(), is(ERROR));
+ }
+
+ @Test
+ public void testGetMessage() {
+ assertThat(e.getMessage(), is(MESSAGE));
+ }
+}
Modified: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/service/PageServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/service/PageServiceTest.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/service/PageServiceTest.java (original)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/service/PageServiceTest.java Wed Aug 17 18:07:09 2011
@@ -19,6 +19,9 @@
package org.apache.rave.portal.service;
+import org.apache.rave.portal.model.PageLayout;
+import org.apache.rave.portal.model.User;
+import org.apache.rave.portal.repository.PageLayoutRepository;
import org.apache.rave.portal.model.Page;
import org.apache.rave.portal.model.Region;
import org.apache.rave.portal.model.RegionWidget;
@@ -46,13 +49,19 @@ public class PageServiceTest {
private RegionRepository regionRepository;
private WidgetRepository widgetRepository;
private RegionWidgetRepository regionWidgetRepository;
+ private PageLayoutRepository pageLayoutRepository;
+ private UserService userService;
private static final long REGION_WIDGET_ID = 5L;
private static final long TO_REGION_ID = 1L;
private static final long FROM_REGION_ID = 2L;
+ private static final String PAGE_LAYOUT_CODE = "layout1";
private Region targetRegion;
private Region originalRegion;
- private Widget widget;
+ private Widget validWidget;
+ private User user;
+ private PageLayout pageLayout;
+ private String defaultPageName = "Main";
@Before
public void setup() {
@@ -61,23 +70,34 @@ public class PageServiceTest {
regionRepository = createNiceMock(RegionRepository.class);
widgetRepository = createNiceMock(WidgetRepository.class);
regionWidgetRepository = createNiceMock(RegionWidgetRepository.class);
- pageService = new DefaultPageService(pageRepository, regionRepository, widgetRepository, regionWidgetRepository);
+ pageLayoutRepository = createMock(PageLayoutRepository.class);
+ userService = createMock(UserService.class);
+ pageService = new DefaultPageService(pageRepository, regionRepository, widgetRepository, regionWidgetRepository, pageLayoutRepository, userService, defaultPageName);
- widget = new Widget(1L, "http://dummy.apache.org/widgets/widget.xml");
+ validWidget = new Widget(1L, "http://dummy.apache.org/widgets/widget.xml");
targetRegion = new Region();
targetRegion.setId(2L);
targetRegion.setRegionWidgets(new ArrayList<RegionWidget>());
- targetRegion.getRegionWidgets().add(new RegionWidget(1L, widget, targetRegion, 0));
- targetRegion.getRegionWidgets().add(new RegionWidget(2L, widget, targetRegion, 1));
- targetRegion.getRegionWidgets().add(new RegionWidget(3L, widget, targetRegion, 2));
+ targetRegion.getRegionWidgets().add(new RegionWidget(1L, validWidget, targetRegion, 0));
+ targetRegion.getRegionWidgets().add(new RegionWidget(2L, validWidget, targetRegion, 1));
+ targetRegion.getRegionWidgets().add(new RegionWidget(3L, validWidget, targetRegion, 2));
originalRegion = new Region();
originalRegion.setId(1L);
originalRegion.setRegionWidgets(new ArrayList<RegionWidget>());
- originalRegion.getRegionWidgets().add(new RegionWidget(4L, widget, targetRegion, 0));
- originalRegion.getRegionWidgets().add(new RegionWidget(5L, widget, targetRegion, 1));
- originalRegion.getRegionWidgets().add(new RegionWidget(6L, widget, targetRegion, 2));
+ originalRegion.getRegionWidgets().add(new RegionWidget(4L, validWidget, targetRegion, 0));
+ originalRegion.getRegionWidgets().add(new RegionWidget(5L, validWidget, targetRegion, 1));
+ originalRegion.getRegionWidgets().add(new RegionWidget(6L, validWidget, targetRegion, 2));
+
+ user = new User();
+ user.setId(1L);
+ user.setUsername("acarlucci");
+
+ pageLayout = new PageLayout();
+ pageLayout.setId(1L);
+ pageLayout.setCode(PAGE_LAYOUT_CODE);
+ pageLayout.setNumberOfRegions(3L);
}
@Test
@@ -92,6 +112,99 @@ public class PageServiceTest {
}
@Test
+ public void createNewPage_noExistingPages() {
+ final String PAGE_NAME = "my new page";
+ final Long EXPECTED_RENDER_SEQUENCE = 1L;
+
+ Page expectedPage = new Page();
+ expectedPage.setName(PAGE_NAME);
+ expectedPage.setOwner(user);
+ expectedPage.setPageLayout(pageLayout);
+ expectedPage.setRenderSequence(EXPECTED_RENDER_SEQUENCE);
+ expectedPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));
+
+ expect(userService.getAuthenticatedUser()).andReturn(user);
+ expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);
+ expect(pageRepository.save(expectedPage)).andReturn(expectedPage);
+ expect(pageRepository.getAllPages(user.getId())).andReturn(new ArrayList<Page>());
+ replay(userService);
+ replay(pageLayoutRepository);
+ replay(pageRepository);
+
+ Page newPage = pageService.addNewPage(PAGE_NAME, PAGE_LAYOUT_CODE);
+ assertThat(newPage.getRenderSequence(), is(EXPECTED_RENDER_SEQUENCE));
+ assertThat(newPage.getName(), is(PAGE_NAME));
+ assertThat(newPage.getRegions().size(), is(pageLayout.getNumberOfRegions().intValue()));
+
+ verify(userService);
+ verify(pageLayoutRepository);
+ verify(pageRepository);
+ }
+
+ @Test
+ public void createNewPage_existingPages() {
+ final String PAGE_NAME = "my new page";
+ final Long EXPECTED_RENDER_SEQUENCE = 2L;
+ List<Page> existingPages = new ArrayList<Page>();
+ existingPages.add(new Page());
+
+ Page expectedPage = new Page();
+ expectedPage.setName(PAGE_NAME);
+ expectedPage.setOwner(user);
+ expectedPage.setPageLayout(pageLayout);
+ expectedPage.setRenderSequence(EXPECTED_RENDER_SEQUENCE);
+ expectedPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));
+
+ expect(userService.getAuthenticatedUser()).andReturn(user);
+ expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);
+ expect(pageRepository.save(expectedPage)).andReturn(expectedPage);
+ expect(pageRepository.getAllPages(user.getId())).andReturn(existingPages);
+ replay(userService);
+ replay(pageLayoutRepository);
+ replay(pageRepository);
+
+ Page newPage = pageService.addNewPage(PAGE_NAME, PAGE_LAYOUT_CODE);
+ assertThat(newPage.getRenderSequence(), is(EXPECTED_RENDER_SEQUENCE));
+ assertThat(newPage.getName(), is(PAGE_NAME));
+ assertThat(newPage.getRegions().size(), is(pageLayout.getNumberOfRegions().intValue()));
+
+ verify(userService);
+ verify(pageLayoutRepository);
+ verify(pageRepository);
+ }
+
+ @Test
+ public void createNewDefaultPage() {
+ final Long EXPECTED_RENDER_SEQUENCE = 1L;
+
+ Page expectedPage = new Page();
+ expectedPage.setName(defaultPageName);
+ expectedPage.setOwner(user);
+ expectedPage.setPageLayout(pageLayout);
+ expectedPage.setRenderSequence(EXPECTED_RENDER_SEQUENCE);
+ expectedPage.setRegions(createEmptyRegionList(pageLayout.getNumberOfRegions()));
+
+ expect(pageLayoutRepository.getByPageLayoutCode(PAGE_LAYOUT_CODE)).andReturn(pageLayout);
+ expect(pageRepository.save(expectedPage)).andReturn(expectedPage);
+ expect(pageRepository.getAllPages(user.getId())).andReturn(new ArrayList<Page>());
+ replay(pageLayoutRepository);
+ replay(pageRepository);
+
+ Page newPage = pageService.addNewDefaultPage(user, PAGE_LAYOUT_CODE);
+ assertThat(newPage.getRenderSequence(), is(EXPECTED_RENDER_SEQUENCE));
+ assertThat(newPage.getName(), is(defaultPageName));
+ assertThat(newPage.getRegions().size(), is(pageLayout.getNumberOfRegions().intValue()));
+
+ verify(pageLayoutRepository);
+ verify(pageRepository);
+ }
+
+ @Test
+ public void getDefaultPageName() {
+ assertThat(pageService.getDefaultPageName(), is(defaultPageName));
+ }
+
+ @Test
public void moveRegionWidget_validMiddle() {
final int newPosition = 0;
createMoveBetweenRegionsExpectations();
@@ -297,4 +410,14 @@ public class PageServiceTest {
assertThat(region.getRegionWidgets().get(i).getRenderOrder(), is(equalTo(i)));
}
}
+
+ private List<Region> createEmptyRegionList(long numberOfRegions) {
+ List<Region> regions = new ArrayList<Region>();
+ int regionCount;
+ for (regionCount = 0; regionCount < numberOfRegions; regionCount++) {
+ Region region = new Region();
+ regions.add(region);
+ }
+ return regions;
+ }
}
\ No newline at end of file
Modified: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java (original)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java Wed Aug 17 18:07:09 2011
@@ -19,6 +19,7 @@
package org.apache.rave.portal.web.api.rpc;
+import org.apache.rave.portal.model.Page;
import org.apache.rave.portal.model.Region;
import org.apache.rave.portal.model.RegionWidget;
import org.apache.rave.portal.service.PageService;
@@ -43,7 +44,7 @@ public class PageApiTest {
@Before
public void setup() {
- pageService = createNiceMock(PageService.class);
+ pageService = createMock(PageService.class);
pageApi = new PageApi(pageService);
}
@@ -188,4 +189,52 @@ public class PageApiTest {
assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.INTERNAL_ERROR));
assertThat(result.getErrorMessage(), is(equalTo(INTERNAL_ERROR_MESSAGE)));
}
+
+ @Test
+ public void addPage_validParams() {
+ final String PAGE_NAME = "My New Page";
+ final String PAGE_LAYOUT_CODE = "layout1";
+
+ expect(pageService.addNewPage(PAGE_NAME, PAGE_LAYOUT_CODE)).andReturn(new Page());
+ replay(pageService);
+ RpcResult result = pageApi.addPage(PAGE_NAME, PAGE_LAYOUT_CODE);
+ verify(pageService);
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getResult(), is(notNullValue()));
+ assertThat(result.isError(), is(false));
+ assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.NO_ERROR));
+ assertThat(result.getErrorMessage(), is(nullValue()));
+ }
+
+ @Test
+ public void addPage_invalidParams() {
+ final String PAGE_NAME = "My New Page";
+ final String PAGE_LAYOUT_CODE = "layout1";
+
+ expect(pageService.addNewPage(PAGE_NAME, PAGE_LAYOUT_CODE)).andThrow(new IllegalArgumentException(PARAM_ERROR_MESSAGE));
+ replay(pageService);
+ RpcResult result = pageApi.addPage(PAGE_NAME, PAGE_LAYOUT_CODE);
+ verify(pageService);
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getResult(), is(nullValue()));
+ assertThat(result.isError(), is(true));
+ assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.INVALID_PARAMS));
+ assertThat(result.getErrorMessage(), is(equalTo(PARAM_ERROR_MESSAGE)));
+ }
+
+ @Test
+ public void addPage_internalError() {
+ final String PAGE_NAME = "My New Page";
+ final String PAGE_LAYOUT_CODE = "layout1";
+
+ expect(pageService.addNewPage(PAGE_NAME, PAGE_LAYOUT_CODE)).andThrow(new RuntimeException(INTERNAL_ERROR_MESSAGE));
+ replay(pageService);
+ RpcResult result = pageApi.addPage(PAGE_NAME, PAGE_LAYOUT_CODE);
+ verify(pageService);
+ assertThat(result, is(notNullValue()));
+ assertThat(result.getResult(), is(nullValue()));
+ assertThat(result.isError(), is(true));
+ assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.INTERNAL_ERROR));
+ assertThat(result.getErrorMessage(), is(equalTo(INTERNAL_ERROR_MESSAGE)));
+ }
}
Modified: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/model/RpcOperationTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/model/RpcOperationTest.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/model/RpcOperationTest.java (original)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/model/RpcOperationTest.java Wed Aug 17 18:07:09 2011
@@ -19,6 +19,7 @@
package org.apache.rave.portal.web.api.rpc.model;
+import org.apache.rave.exception.DuplicateItemException;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.*;
@@ -67,4 +68,17 @@ public class RpcOperationTest {
assertThat(result.getResult(), is(nullValue()));
assertThat(result.getErrorCode(), is(equalTo(RpcResult.ErrorCode.INTERNAL_ERROR)));
}
+ @Test
+ public void execute_duplicateItemException() {
+ RpcOperation<String> valid = new RpcOperation<String>() {
+ @Override
+ public String execute() {
+ throw new DuplicateItemException("Duplicate Item Error");
+ }
+ };
+
+ RpcResult<String> result = valid.getResult();
+ assertThat(result.getResult(), is(nullValue()));
+ assertThat(result.getErrorCode(), is(equalTo(RpcResult.ErrorCode.DUPLICATE_ITEM)));
+ }
}
Modified: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/model/RpcResultTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/model/RpcResultTest.java?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/model/RpcResultTest.java (original)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/model/RpcResultTest.java Wed Aug 17 18:07:09 2011
@@ -28,11 +28,11 @@ import static org.junit.Assert.assertTha
public class RpcResultTest {
@Test
- public void corretDefault_noError() {
+ public void correctDefault_noError() {
assertThat(new RpcResult<String>(false).getErrorCode(), is(equalTo(RpcResult.ErrorCode.NO_ERROR)));
}
@Test
- public void corretDefault_error() {
+ public void correctDefault_error() {
assertThat(new RpcResult<String>(true).getErrorCode(), is(equalTo(RpcResult.ErrorCode.INTERNAL_ERROR)));
}
}
Modified: incubator/rave/trunk/rave-portal/src/test/javascript/raveApiSpec.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/javascript/raveApiSpec.js?rev=1158852&r1=1158851&r2=1158852&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/javascript/raveApiSpec.js (original)
+++ incubator/rave/trunk/rave-portal/src/test/javascript/raveApiSpec.js Wed Aug 17 18:07:09 2011
@@ -145,6 +145,26 @@ describe("Rave API", function() {
});
});
+
+ describe("addPage", function() {
+ it("posts the correct values to RPC service for adding a new page", function() {
+
+ var newPageName = "my new page";
+ var newPageLayoutCode = "layout1";
+
+ $.post = function(url, data, callback) {
+ expect(url).toEqual("api/rpc/page/add");
+ expect(data.pageName).toEqual(newPageName);
+ expect(data.pageLayoutCode).toEqual(newPageLayoutCode);
+ expect(typeof(callback)).toEqual("function");
+ return {
+ error: function(a, b, c) {
+ }
+ }
+ };
+ rave.api.rpc.addPage({pageName: newPageName, pageLayoutCode: newPageLayoutCode});
+ });
+ });
describe("Error handling", function() {
it("displays the appropriate alert when invalid parameters are passed", function() {