You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by mf...@apache.org on 2011/04/01 18:42:42 UTC

svn commit: r1087796 [11/37] - in /incubator/rave/donations/mitre-osec: ./ conf/ db/ db/data/ db/sequences/ db/tables/ lib/ lib/apache-commons/ lib/apache-taglibs/ lib/build/ lib/build/cobertura/ lib/eclipselink/ lib/freemarker/ lib/google-collections/...

Added: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultPageService.java
URL: http://svn.apache.org/viewvc/incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultPageService.java?rev=1087796&view=auto
==============================================================================
--- incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultPageService.java (added)
+++ incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultPageService.java Fri Apr  1 16:42:22 2011
@@ -0,0 +1,586 @@
+/*
+ * 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.mitre.portal.service.impl;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mitre.portal.model.*;
+import org.mitre.portal.repository.*;
+import org.mitre.portal.repository.util.JpaConstants;
+import org.mitre.portal.security.SecurityTokenService;
+import org.mitre.portal.service.PageService;
+import org.mitre.portal.service.exception.DuplicatePageNameException;
+import org.mitre.portal.service.exception.PageException;
+import org.mitre.portal.service.exception.RegionGadgetNotFoundException;
+import org.mitre.portal.service.exception.UnknownPageException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.IncorrectResultSizeDataAccessException;
+import org.springframework.orm.jpa.JpaSystemException;
+import org.springframework.stereotype.Service;
+
+import java.sql.SQLIntegrityConstraintViolationException;
+import java.util.ArrayList;
+import java.util.List;
+import org.mitre.portal.service.exception.PageLayoutNotFoundException;
+import org.mitre.portal.service.exception.PageNotFoundException;
+import org.mitre.portal.service.exception.PageTemplateNotFoundException;
+import org.mitre.portal.service.exception.PageTemplateOwnerTypeNotFoundException;
+import org.mitre.portal.service.exception.RegionNotFoundException;
+import org.springframework.security.access.prepost.PostAuthorize;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.access.prepost.PreFilter;
+import org.springframework.transaction.annotation.Transactional;
+
+
+/**
+ * @author ACARLUCCI
+ */
+@Service(value = "pageService")
+public class DefaultPageService implements PageService {
+    private static final Log log = LogFactory.getLog(DefaultPageService.class);
+
+    private PageRepository pageRepository;
+    private RegionRepository regionRepository;
+    private RegionGadgetRepository regionGadgetRepository;
+    private PersonGadgetRepository personGadgetRepository;
+    private PageLayoutRepository pageLayoutRepository;
+    private PageTemplateOwnerTypeRepository pageTemplateOwnerTypeRepository;
+    private PageTemplateRepository pageTemplateRepository;
+    private SecurityTokenService securityTokenService;
+
+    @Autowired
+    public DefaultPageService(PageRepository pageRepository,
+                              RegionRepository regionRepository,
+                              RegionGadgetRepository regionGadgetRepository,
+                              PersonGadgetRepository personGadgetRepository,
+                              PageLayoutRepository pageLayoutRepository,
+                              PageTemplateOwnerTypeRepository pageTemplateOwnerTypeRepository,
+                              PageTemplateRepository pageTemplateRepository,
+                              SecurityTokenService securityTokenService) {
+        this.pageRepository = pageRepository;
+        this.regionRepository = regionRepository;
+        this.regionGadgetRepository = regionGadgetRepository;
+        this.personGadgetRepository = personGadgetRepository;
+        this.pageLayoutRepository = pageLayoutRepository;
+        this.pageTemplateOwnerTypeRepository = pageTemplateOwnerTypeRepository;
+        this.pageTemplateRepository = pageTemplateRepository;
+        this.securityTokenService = securityTokenService;
+    }
+
+    /**
+     * *************
+     * Page methods
+     * **************
+     */
+
+    @Override
+    @PostAuthorize("returnObject == null or returnObject.userId == principal.userId")
+    public Page getPage(Long pageId) throws PageNotFoundException {
+        Page page = null;
+
+        try {
+            page = pageRepository.get(pageId);
+            injectToken(page);
+        }
+        catch (IncorrectResultSizeDataAccessException e) {
+            throw new PageNotFoundException(pageId);
+        }
+        return page;
+    }
+
+    @Override
+    @PreAuthorize("#user.userId == principal.userId")
+    public Page findPage(Container container, String pageName, Person user) {
+        Page page = pageRepository.find(container, pageName, user.getUserId());
+        injectToken(page);
+        return page;
+    }
+
+    @Override
+    @PreAuthorize("#user.userId == principal.userId")
+    public Page findDefaultPage(Container container, Person user) {
+        Page page = pageRepository.findDefault(container, user.getUserId());
+        injectToken(page);
+        return page;
+    }
+
+    @Override
+    @PreAuthorize("#user.userId == principal.userId")
+    public List<Page> findPages(Container container, Person user) {
+        List<Page> pages = pageRepository.find(container, user.getUserId());
+        for (Page page : pages) {
+            injectToken(page);
+        }
+        return pages;
+    }
+
+    @Override
+    @PreAuthorize("#page.userId == principal.userId")
+    public void save(Page page) throws PageException {
+        try {
+            pageRepository.save(page);
+        }
+        catch (JpaSystemException e) {
+            // check to see if the database error is a unique page name constraint violation
+            // if so throw an exception
+            if (ExceptionUtils.getRootCause(e) instanceof SQLIntegrityConstraintViolationException) {
+                SQLIntegrityConstraintViolationException rootException = (SQLIntegrityConstraintViolationException) ExceptionUtils.getRootCause(e);
+                if (rootException.getMessage() != null && rootException.getMessage().contains(JpaConstants.Constraint.UNIQUE_PAGE_NAME)) {
+                    throw new DuplicatePageNameException(page.getName(), page.getUserId());
+                } else {
+                    throw new UnknownPageException("Unknown SQLIntegrityConstraintViolationException thrown: ", rootException);
+                }
+            } else {
+                throw new UnknownPageException("Unknown JpaSystemException thrown: ", e);
+            }
+        }
+    }
+
+    @Override
+    @PreAuthorize("#page.userId == principal.userId")
+    public void delete(Page page) {
+        pageRepository.delete(page);
+    }
+
+    @Override
+    @PreAuthorize("#page.userId == principal.userId")
+    public void add(Gadget gadget, Page page) {
+        // add the new gadget to the first region and
+        // in the first position
+        regionRepository.addGadget(page.getRegion(Region.IDENTIFIER_PREFIX + "1"), gadget, Region.Location.BEGINNING);
+    }
+
+    @Override
+    @PreAuthorize("#regionGadget.personGadget.userId == principal.userId")
+    public void move(RegionGadget regionGadget, Long toRegionId, int toRenderSequence) {
+        pageRepository.move(regionGadget, toRegionId, toRenderSequence);
+    }
+    
+    @Override
+    @Transactional
+    @PreAuthorize("#regionGadget.personGadget.userId == principal.userId")
+    public void move(RegionGadget regionGadget, Region toRegion, int toRenderSequence){
+    	if (regionGadget == null)
+    		return;
+    	if (toRegion == null)
+    		return;
+    	regionGadgetRepository.move(regionGadget, toRegion, toRenderSequence);
+    	save(toRegion);
+    	save(regionGadget.getRegion());
+    	
+    	
+    }
+
+    @Override
+    @PreFilter("filterObject.userId == principal.userId")
+    public void updatePageRenderSequences(List<Page> pages) {
+        pageRepository.updatePageRenderSequences(pages);
+    }
+
+    @Override
+    public void updatePageLayout(Page page, PageLayout newPageLayout) {
+        PageLayout currentPageLayout = page.getPageLayout();
+        if (newPageLayout != null && !currentPageLayout.equals(newPageLayout)) {
+            // if decreasing regions...
+            if (currentPageLayout.getNumRegions() > newPageLayout.getNumRegions()) {
+                Region moveToRegion = page.getRegion(Region.IDENTIFIER_PREFIX + newPageLayout.getNumRegions());
+                for (long i = currentPageLayout.getNumRegions(); i > newPageLayout.getNumRegions(); i--) {
+                    Region moveFromRegion = page.getRegion(Region.IDENTIFIER_PREFIX + i);
+                    for (RegionGadget rg : moveFromRegion.getRegionGadgetList()) {
+                        // two way update - update region and regiongadget object
+                        rg.setRegion(moveToRegion);
+                        moveToRegion.getRegionGadgetList().add(rg);
+                    }
+                    // once gadgets have been moved to new region remove the old "downsized" region
+                    page.getRegionList().remove(moveFromRegion);
+                }
+                // update the render sequences
+                moveToRegion.updateRegionGadgetRenderSequences();
+            }
+            // if increasing regions...
+            else if (currentPageLayout.getNumRegions() < newPageLayout.getNumRegions()) {
+                // create empty new regions
+                for (long i = currentPageLayout.getNumRegions() + 1L; i <= newPageLayout.getNumRegions(); i++) {
+                    Region r = new Region();
+                    r.setName(Region.IDENTIFIER_PREFIX + i);
+                    r.setPage(page);
+                    page.getRegionList().add(r);
+                }
+            }
+            page.setPageLayout(newPageLayout);
+        }
+    }
+
+    /**
+     * *************
+     * Region methods
+     * **************
+     */
+
+    @Override
+    @PostAuthorize("returnObject == null or returnObject.page.userId == principal.userId")
+    public Region getRegion(Long regionId) throws RegionNotFoundException {
+        Region r = null;
+        try {
+            r = regionRepository.get(regionId);
+        }
+        catch (IncorrectResultSizeDataAccessException e) {
+            throw new RegionNotFoundException(regionId);
+        }
+        return r;
+    }
+
+    @Override
+    @PreAuthorize("#page.userId == principal.userId")
+    public List<Region> findRegions(Page page) {
+        return regionRepository.find(page);
+    }
+
+    @Override
+    @PreAuthorize("#region.page.userId == principal.userId")
+    public void add(Gadget gadget, Region region, Region.Location location) {
+        regionRepository.addGadget(region, gadget, location);
+    }
+
+    @Override
+    @PreAuthorize("#region.page.userId == principal.userId")
+    public void save(Region region) {
+        regionRepository.save(region);
+    }
+
+    @Override
+    @PreAuthorize("#page.userId == principal.userId")
+    public Region findRegion(String regionName, Page page) {
+        return regionRepository.find(regionName, page);
+    }
+
+    @Override
+    @Transactional
+    @PreAuthorize("#regionGadget.personGadget.userId == principal.userId")
+    public void delete(RegionGadget regionGadget) {
+        PersonGadget pg = regionGadget.getPersonGadget();
+
+        // delete the region gadget
+        log.debug("deleting regionGadget " + regionGadget);
+        regionRepository.delete(regionGadget);        
+    }
+
+
+    /**
+     * ********************
+     * RegionGadget methods
+     * *********************
+     */
+
+    @Override
+    @PostAuthorize("returnObject == null or returnObject.personGadget.userId == principal.userId")
+    public RegionGadget getRegionGadget(Long regionGadgetId) throws RegionGadgetNotFoundException
+    {
+        RegionGadget rg = null;
+        try {
+            rg = regionGadgetRepository.get(regionGadgetId);
+        }
+        catch (IncorrectResultSizeDataAccessException e) {
+            throw new RegionGadgetNotFoundException(regionGadgetId);
+        }
+
+        return rg;
+    }
+
+    @Override
+    @PreAuthorize("#region.page.userId == principal.userId")
+    public List<RegionGadget> findRegionGadgets(Region region) {
+        return regionGadgetRepository.find(region);
+    }
+
+    @Override
+    @PreAuthorize("#regionGadget.personGadget.userId == principal.userId")
+    public void move(RegionGadget regionGadget, int newRenderSequence) {
+        regionRepository.move(regionGadget, newRenderSequence);
+    }
+
+    @Override
+    @PreAuthorize("#regionGadget.personGadget.userId == principal.userId")
+    public void save(RegionGadget regionGadget) {        
+        regionGadgetRepository.save(regionGadget);
+    }
+
+    /**
+     * ********************
+     * PersonGadget methods
+     * *********************
+     */
+    @Override
+    @PreAuthorize("#personGadget.userId == principal.userId")
+    public void save(PersonGadget personGadget) {
+        personGadgetRepository.save(personGadget);
+    }
+    /**
+     * ********************
+     * PageLayout methods
+     * *********************
+     */
+
+    @Override
+    public PageLayout getPageLayout(Long pageLayoutId) throws PageLayoutNotFoundException {
+        PageLayout pl = null;
+        try {
+            pl = pageLayoutRepository.get(pageLayoutId);
+        }
+        catch (IncorrectResultSizeDataAccessException e) {
+            throw new PageLayoutNotFoundException(pageLayoutId);
+        }
+        return pl;
+    }
+
+    @Override
+    public List<PageLayout> getAllPageLayouts() {
+        return pageLayoutRepository.findAll();
+    }
+
+    @Override
+    public List<PageLayout> getAllUserSelectablePageLayouts() {
+        // because eclipselink has a bug where you can't query against booleans
+        // we will filter out the non-user selectable objects in this service layer
+        List<PageLayout> list = new ArrayList<PageLayout>();
+        for (PageLayout pageLayout : pageLayoutRepository.findAll()) {
+            if (pageLayout.isUserSelectable()) list.add(pageLayout);
+        }
+        
+        return list;
+    }
+
+    /**
+     * ************************
+     * PageTemplateOwnerType methods
+     * *************************
+     */
+
+    @Override
+    public PageTemplateOwnerType getPageTemplateOwnerType(String code) throws PageTemplateOwnerTypeNotFoundException {
+        PageTemplateOwnerType ptt = null;
+        try {
+            ptt = pageTemplateOwnerTypeRepository.get(code);
+        }
+        catch (IncorrectResultSizeDataAccessException e) {
+            throw new PageTemplateOwnerTypeNotFoundException(code);
+        }
+        return ptt;
+    }
+
+    @Override
+    public List<PageTemplateOwnerType> getAllPageTemplateOwnerTypes() {
+        return pageTemplateOwnerTypeRepository.findAll();
+    }
+
+    /**
+     * ************************
+     * PageTemplate methods
+     * *************************
+     */
+
+    @Override
+    public PageTemplate getPageTemplate(Long pageTemplateId) throws PageTemplateNotFoundException {
+        PageTemplate pt = null;
+        try {
+            pt = pageTemplateRepository.get(pageTemplateId);
+        }
+        catch (IncorrectResultSizeDataAccessException e) {
+            throw new PageTemplateNotFoundException(pageTemplateId);
+        }
+        return pt;
+    }
+
+    @Override
+    public List<PageTemplate> getAllPageTemplates() {
+        return pageTemplateRepository.findAll();
+    }
+
+    @Override
+    public PageTemplate getDefaultPageTemplate() throws PageTemplateNotFoundException {
+        PageTemplate pt = null;
+        try {
+            pt = pageTemplateRepository.getDefault();
+        }
+        catch (IncorrectResultSizeDataAccessException e) {
+            throw new PageTemplateNotFoundException();
+        }
+        return pt;
+    }
+
+    @Override
+    public PageTemplate find(Container container, String name) {
+        return pageTemplateRepository.find(container, name);
+    }
+
+    @Override
+    public List<PageTemplate> find(Container container, PageTemplateOwnerType pageTemplateOwnerType) {
+        return pageTemplateRepository.find(container, pageTemplateOwnerType);
+    }
+
+    @Override
+    @PreAuthorize("#user.userId == principal.userId")
+    public Page convert(PageTemplate pageTemplate, Person user) {
+
+        Page page = new Page();
+
+        page.setContainer(pageTemplate.getContainer());
+        page.setName(pageTemplate.getName());
+        page.setPageLayout(pageTemplate.getPageLayout());
+        page.setUserId(user.getUserId());
+        page.setFixedLayout(pageTemplate.isFixedLayout());
+
+        // convert the PageTemplateGadgets into their appropriate region spots
+        convertPageTemplateRegionsToRegionList(page, pageTemplate, user.getUserId());
+
+        return page;
+    }
+
+    /**
+     * ********************
+     * Private methods
+     * *********************
+     */
+    private void convertPageTemplateRegionsToRegionList(Page page, PageTemplate pageTemplate, String userId) {
+        List<PageTemplateRegion> pageTemplateRegionList = pageTemplate.getPageTemplateRegionList();
+
+        // if the page template doesn't have any pageTemplateRegions (such as the 'empty' template)
+        // create the region skeletons based on the number of regions in the page layout
+        if (pageTemplateRegionList == null || pageTemplateRegionList.isEmpty()) {
+            createRegionSkeletons(page, pageTemplate.getPageLayout().getNumRegions());
+            return;
+        }
+
+        // create the skeleton regionList based on the pageTemplateRegions
+        createRegionSkeletons(page, pageTemplateRegionList);
+
+        // add the template gadgets to their appropriate regions
+        List<Region> regionList = page.getRegionList();
+        for (Region region : regionList) {
+            log.debug("region: " + region.getName());
+
+            ArrayList<RegionGadget> regionGadgetList = new ArrayList<RegionGadget>();
+            for (PageTemplateRegion pageTemplateRegion : pageTemplateRegionList) {
+                if (region.getName().equals(pageTemplateRegion.getRegionName()) && pageTemplateRegion.getPageTemplateGadgetList() != null) {
+                    //log.debug("found matching pageTemplateGadget region name!  creating new regionGadget...");
+                    for (PageTemplateGadget pageTemplateGadget : pageTemplateRegion.getPageTemplateGadgetList()) {
+                        // create a PersonGadget
+                        PersonGadget personGadget = new PersonGadget();
+                        personGadget.setGadget(pageTemplateGadget.getGadget());
+                        personGadget.setUserId(userId);
+
+                        // create a RegionGadget
+                        RegionGadget regionGadget = new RegionGadget();
+                        regionGadget.setRenderSeq(pageTemplateGadget.getRenderSeq());
+                        regionGadget.setRegion(region);
+                        regionGadget.setPersonGadget(personGadget);
+
+                        log.debug("adding gadget(" + regionGadget.getPersonGadget().getGadget().getGadgetId() + ") " + regionGadget.getPersonGadget().getGadget().getTitle() + " to " + region.getName());
+                        regionGadgetList.add(regionGadget);
+                    }
+                    
+                    break;
+                }
+            }
+
+            region.setRegionGadgetList(regionGadgetList);
+        }
+    }
+
+    /**
+     * Creates and assigns a new regionList for the page based on the
+     * List of PageTemplateRegion objects.  New Region objects get created and the
+     * page and name values are assigned.  The new list gets assigned to the page.
+     *
+     * @param page       The Page object to create the regionList skeleton
+     * @param pageTemplateRegionList  a list of PageTemplateRegions to create as Regions
+     * @throws IllegalArgumentException if the Page object is null
+     */
+    private void createRegionSkeletons(Page page, List<PageTemplateRegion> pageTemplateRegionList) {
+        if (page == null)
+            throw new IllegalArgumentException("page should not be null");
+
+        // make sure the size is valid
+        if (pageTemplateRegionList.size() < 1)
+            throw new IllegalArgumentException("number of page template regions must be greater than or equal to 1 (" + pageTemplateRegionList.size() + " passed in)");
+
+        ArrayList<Region> regionList = new ArrayList<Region>();
+        for (PageTemplateRegion ptr : pageTemplateRegionList) {
+            Region region = new Region();
+            region.setName(ptr.getRegionName());
+            region.setPage(page);
+            regionList.add(region);
+        }
+
+        page.setRegionList(regionList);
+    }
+    
+    /**
+     * Creates and assigns a new regionList for the page based on the number of
+     * regions passed into the function.  New Region objects get created and the
+     * page and name values are assigned.  The new list gets assigned to the page.
+     * NOTE: the names of the regions are generated automatically using the
+     * Region.IDENTIFIER_PREFIX and and iteration up the the numRegions value
+     * (_1, _2, _3, etc)
+     *
+     * @param page       The Page object to create the regionList skeleton
+     * @param numRegions The number of skeleton regions to create
+     * @throws IllegalArgumentException if the Page object is null
+     */
+    private void createRegionSkeletons(Page page, long numRegions) {
+        if (page == null)
+            throw new IllegalArgumentException("page should not be null");
+
+        // make sure the numRegions value is valid
+        if (numRegions < 1)
+            throw new IllegalArgumentException("numRegions must be greater than or equal to 1 (" + numRegions + " passed in)");
+
+        ArrayList<Region> regionList = new ArrayList<Region>();
+        for (int i = 0; i < numRegions; i++) {
+            Region region = new Region();
+            // region names use a 1 based index
+            region.setName(Region.IDENTIFIER_PREFIX + (i + 1));
+            region.setPage(page);
+            regionList.add(region);
+        }
+
+        page.setRegionList(regionList);
+    }
+
+    private void injectToken(Page page) {
+        if (page != null) {
+            log.debug("BEGIN token injection for page: " + page.toString());
+            for (Region region : page.getRegionList()) {
+                log.debug("Setting token for gadgets in region: " + region.toString());
+                for (RegionGadget regionGadget : region.getRegionGadgetList()) {
+                    PersonGadget pGadget = regionGadget.getPersonGadget();
+                    log.debug("Setting token for personGadet: " + pGadget);
+                    try {
+                        pGadget.setSecurityToken(securityTokenService.getEncryptedEncodedSecurityToken(pGadget));
+                    } catch (Exception e) {
+                        pGadget.setSecurityToken("");
+                    }
+                }
+            }
+        }
+    }
+
+}
\ No newline at end of file

Propchange: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultPageService.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultPersonService.java
URL: http://svn.apache.org/viewvc/incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultPersonService.java?rev=1087796&view=auto
==============================================================================
--- incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultPersonService.java (added)
+++ incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultPersonService.java Fri Apr  1 16:42:22 2011
@@ -0,0 +1,52 @@
+/*
+ * 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.mitre.portal.service.impl;
+
+import org.mitre.portal.model.Person;
+import org.mitre.portal.repository.PersonRepository;
+import org.mitre.portal.service.PersonService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ *
+ * @author ACARLUCCI
+ */
+@Service(value="personService")
+public class DefaultPersonService implements PersonService {
+    private PersonRepository personRepository;
+
+    @Autowired
+    public DefaultPersonService(PersonRepository personRepository) {
+        this.personRepository = personRepository;
+    }
+
+    @Override
+    public Person getPersonByUserId(String employeeNumber) {
+        return personRepository.getPersonByUserId(employeeNumber);
+    }
+
+    @Override
+    public Person getPersonByUsername(String sui) {
+        return personRepository.getPersonByUsername(sui);
+    }
+}
\ No newline at end of file

Propchange: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultPersonService.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultShindigService.java
URL: http://svn.apache.org/viewvc/incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultShindigService.java?rev=1087796&view=auto
==============================================================================
--- incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultShindigService.java (added)
+++ incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultShindigService.java Fri Apr  1 16:42:22 2011
@@ -0,0 +1,96 @@
+/*
+ * 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.mitre.portal.service.impl;
+
+import java.io.IOException;
+
+import java.net.URL;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.URIException;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mitre.portal.model.Container;
+import org.mitre.portal.service.ShindigService;
+import org.mitre.portal.service.util.PostMethodFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * @author ACARLUCCI
+ */
+@Service
+public class DefaultShindigService implements ShindigService {
+    private static final Log log = LogFactory.getLog(DefaultShindigService.class);
+
+    // the Shindig metadata context
+    private final String SHINDIG_METADATA_PATH = "/metadata";
+    
+    private String shindigUrl;
+    private HttpClient httpClient;
+    private PostMethodFactory postMethodFactory;
+
+    @Autowired
+    public DefaultShindigService(@Value("${shindig.protocol}") String shindigProtocol,
+                                 @Value("${shindig.root}") String shindigRoot,
+                                 @Value("${shindig.gadget_servlet}") String shindigGadgetServlet,
+                                 HttpClient httpClient, PostMethodFactory postMethodFactory) throws URIException  {
+        this.shindigUrl = shindigProtocol + shindigRoot + shindigGadgetServlet;
+        this.httpClient = httpClient;
+        this.postMethodFactory = postMethodFactory;
+    }
+
+    @Override
+    public String invokeShindigMetadataPost(URL gadgetUrl, Container container) {
+        // generate the json request to be sent to the metadata servlet
+        String postData = "{\"gadgets\":[{\"url\":\"" + gadgetUrl.toString() + "\"}],\"context\":{\"country\":\"US\",\"language\":\"en\",\"view\":\"home\",\"container\":\""+ container.getName() + "\"}}";
+        log.debug("requestContent: " + postData);
+
+        String responseString = "";
+        PostMethod postMethod = null;
+        try {
+            // create a new postMethod from the factory - reusing the same PostMethod
+            // object was causing problems so this is a cleaner solution
+            postMethod = postMethodFactory.getInstance(shindigUrl + SHINDIG_METADATA_PATH, postData, "application/json", "UTF-8");
+
+            // execute the http post to shindig
+            int returnCode = httpClient.executeMethod(postMethod);
+            log.info("shindig metadata response code: " + returnCode);
+            if (returnCode != HttpStatus.SC_OK) {
+                throw new IOException("unable to connect to Shindig Metadata Servlet: http code " + returnCode);
+            }
+            // grab the response from the post
+            responseString = postMethod.getResponseBodyAsString();
+           
+            log.debug("shindig metadata raw response: " + responseString);
+        } catch (Exception e) {
+            log.error("unable to get gadget metadata: " + e);
+        } finally {
+            // even though we are creating new postMethods with each call still
+            // cleanly release the connection
+            postMethod.releaseConnection();
+        }
+
+        return responseString;
+    }
+}

Propchange: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultShindigService.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultStatisticsService.java
URL: http://svn.apache.org/viewvc/incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultStatisticsService.java?rev=1087796&view=auto
==============================================================================
--- incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultStatisticsService.java (added)
+++ incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultStatisticsService.java Fri Apr  1 16:42:22 2011
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.mitre.portal.service.impl;
+
+import java.util.List;
+import java.util.Map;
+import org.mitre.portal.model.ContainerRegistry;
+import org.mitre.portal.model.util.GadgetStatistics;
+import org.mitre.portal.repository.StatisticsRepository;
+import org.mitre.portal.service.StatisticsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * @author Sean Cooper
+ */
+@Service(value = "statisticsService")
+public class DefaultStatisticsService implements StatisticsService {
+
+    StatisticsRepository repository;
+
+    @Autowired
+    public DefaultStatisticsService(StatisticsRepository repository)
+    {
+        this.repository = repository;
+    }
+
+    @Override
+    public Map<String, GadgetStatistics> getAllGadgetStatistics(List<ContainerRegistry> containerRegistryList) {
+        return repository.getAllGadgetStatistics(containerRegistryList);
+    }
+
+    @Override
+    public Map<String, GadgetStatistics> getAllGadgetStatistics(final String userId, List<ContainerRegistry> containerRegistryList) {
+        return repository.getAllGadgetStatistics(userId, containerRegistryList);
+    }
+
+    @Override
+    public GadgetStatistics getGadgetStatistics(final Long gadgetId) {
+        return repository.getGadgetStatistics(gadgetId);
+    }
+
+    @Override
+    public GadgetStatistics getGadgetStatistics(final Long gadgetId, final String userId) {
+        return repository.getGadgetStatistics(gadgetId, userId);
+    }
+}

Propchange: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultStatisticsService.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultWizardService.java
URL: http://svn.apache.org/viewvc/incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultWizardService.java?rev=1087796&view=auto
==============================================================================
--- incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultWizardService.java (added)
+++ incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultWizardService.java Fri Apr  1 16:42:22 2011
@@ -0,0 +1,114 @@
+/*
+ * 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.mitre.portal.service.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mitre.portal.model.Person;
+import org.mitre.portal.model.UserWizardCompleted;
+import org.mitre.portal.model.Wizard;
+import org.mitre.portal.repository.UserWizardCompletedRepository;
+import org.mitre.portal.repository.WizardRepository;
+import org.mitre.portal.service.PersonService;
+import org.mitre.portal.service.WizardService;
+import org.mitre.portal.service.exception.WizardNotFoundException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.IncorrectResultSizeDataAccessException;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * @author ACARLUCCI
+ */
+@Service(value="wizardService")
+public class DefaultWizardService implements WizardService {
+    protected final Log log = LogFactory.getLog(getClass());
+    private final WizardRepository wizardRepository;
+    private final UserWizardCompletedRepository userWizardCompletedRepository;   
+
+    @Autowired
+    public DefaultWizardService(WizardRepository wizardRepository,
+                                UserWizardCompletedRepository userWizardCompletedRepository)
+    {
+        this.userWizardCompletedRepository = userWizardCompletedRepository;
+        this.wizardRepository = wizardRepository;
+    }
+
+    @Override
+    public Wizard getWizard(Long wizardId) throws WizardNotFoundException {
+        Wizard wizard = null;
+        try {
+            wizard = wizardRepository.get(wizardId);
+        }
+        catch (IncorrectResultSizeDataAccessException e) {
+            throw new WizardNotFoundException(wizardId);
+        }
+        return wizard;
+    }
+
+    @Override
+    public Wizard findWizard(String name) {
+        return wizardRepository.find(name);
+    }
+
+    @Override
+    public List<Wizard> findAllWizards() {
+        return wizardRepository.findAll();
+    }
+
+    @Override
+    @PreAuthorize("#user.userId == principal.userId")
+    public List<Wizard> findNonCompletedWizardsByUser(Person user) {
+        log.debug("checking for non-completed wizards for " + user);
+        List<Wizard> nonCompletedWizardList = new ArrayList<Wizard>();
+        List<Wizard> allWizardList = findAllWizards();
+        List<UserWizardCompleted> userWizardCompletedList = userWizardCompletedRepository.find(user.getUserId());
+
+        for (Wizard wizard : allWizardList) {
+            boolean foundCompletedWizard = false;
+            for (UserWizardCompleted uwc : userWizardCompletedList) {
+                if (uwc.getWizard().equals(wizard)) {
+                    foundCompletedWizard = true;
+                    break;
+                }
+            }
+            if (!foundCompletedWizard) {
+                nonCompletedWizardList.add(wizard);
+            }
+        }
+        log.debug("non-completed wizards for " + user + ": " + nonCompletedWizardList.size());
+        return nonCompletedWizardList;
+    }
+
+    @Override
+    @PreAuthorize("#userWizardCompleted.userId == principal.userId")
+    public void save(UserWizardCompleted userWizardCompleted) {
+        userWizardCompletedRepository.save(userWizardCompleted);
+    }
+
+    @Override
+    @PreAuthorize("#userWizardCompleted.userId == principal.userId")
+    public void delete(UserWizardCompleted userWizardCompleted) {
+        userWizardCompletedRepository.delete(userWizardCompleted);
+    }
+}

Propchange: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/DefaultWizardService.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/FreemarkerEmailService.java
URL: http://svn.apache.org/viewvc/incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/FreemarkerEmailService.java?rev=1087796&view=auto
==============================================================================
--- incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/FreemarkerEmailService.java (added)
+++ incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/FreemarkerEmailService.java Fri Apr  1 16:42:22 2011
@@ -0,0 +1,241 @@
+/*
+ * 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.mitre.portal.service.impl;
+
+import freemarker.template.Template;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mitre.portal.model.Gadget;
+import org.mitre.portal.model.GadgetAuthorType;
+import org.mitre.portal.model.GadgetComment;
+import org.mitre.portal.model.Person;
+import org.mitre.portal.service.EmailService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.stereotype.Service;
+import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
+import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author ACARLUCCI
+ */
+@Service(value = "emailService")
+public class FreemarkerEmailService implements EmailService {
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    private final String FM_MAIL_DIR = "mail/";
+    private final String FM_GADGET_COMMENT = FM_MAIL_DIR + "gadget_comment.ftl";
+    private final String FROM_ADDRESS_NAME = "Gadget Feedback Notification";
+
+    private JavaMailSender mailSender;
+    private String fromAddress;
+    private String feedbackEmailAddress;
+    private FreeMarkerConfigurer freemarkerConfigurer;
+
+    private boolean enabled;
+    private boolean debug;
+    private String debugAddress;
+
+    @Autowired
+    public FreemarkerEmailService(JavaMailSender mailSender,
+                                  FreeMarkerConfigurer freemarkerConfigurer,
+                                  @Value("${mail.enabled}") boolean enabled,
+                                  @Value("${mail.noreplyFromAddress}") String fromAddress,
+                                  @Value("${mail.feedbackEmailAddress}") String feedbackEmailAddress,
+                                  @Value("${mail.emailServiceDebugMode}") boolean debug,
+                                  @Value("${mail.emailServiceDebugAddress}") String debugAddress) {
+
+        this.mailSender = mailSender;
+        this.freemarkerConfigurer = freemarkerConfigurer;
+        this.enabled = enabled;
+        this.fromAddress = fromAddress;
+        this.feedbackEmailAddress = feedbackEmailAddress;
+        this.debug = debug;
+        this.debugAddress = debugAddress;
+    }
+
+    @Override
+    public void sendGadgetCommentNotification(GadgetComment gadgetComment, Person user, boolean isUpdatedComment, String applicationHostname, int applicationPort, String applicationContextPath) throws MessagingException {
+        //Only build and send the message if service is enabled
+        if (enabled) {
+            //Build the message from the parameters
+            MimeMessageHelper helper = buildMessage(gadgetComment, user, isUpdatedComment, applicationHostname, applicationPort, applicationContextPath);
+
+            // Send the message
+            mailSender.send(helper.getMimeMessage());
+        }
+    }
+
+
+    /**
+     * Builds the message to be sent
+     *
+     * @param gadgetComment          the comment to build the message for
+     * @param user                   the user to send the message to
+     * @param isUpdatedComment       flag indicating if the comment is an update
+     * @param applicationHostname    the hostname of the application
+     * @param applicationPort        the port of the application
+     * @param applicationContextPath the context path of the application
+     * @return a valid MimeMessageHelper containing the message to be sent
+     * @throws MessagingException if the message is invalid
+     */
+    private MimeMessageHelper buildMessage(GadgetComment gadgetComment, Person user, boolean isUpdatedComment, String applicationHostname, int applicationPort, String applicationContextPath) throws MessagingException {
+        Map<String, Object> model = new HashMap<String, Object>();
+        MimeMessageHelper helper = getMimeMessageHelper();
+        boolean sendAsHtml = true;
+        Gadget gadget = gadgetComment.getGadget();
+
+        //set up the receipients for the message
+        List<String> tos = new ArrayList<String>();
+
+        // if the gadget author type is CI&T or External, send feedback to the mymii feedback list
+        GadgetAuthorType gat = gadget.getGadgetAuthorType();
+        //TODO this is MITRE specific
+        if ("CIT".equals(gat.getCode()) || "EXT".equals(gat.getCode())) {
+            tos.add(feedbackEmailAddress);
+        } else {
+            // ...else send it to the gadget author email if one is supplied
+            if ("EMAIL".equals(gadget.getGadgetSupportLinkType().getCode())) {
+                tos.add(gadget.getSupportLink());
+            }
+        }
+
+        setRecipients(tos, helper, model);
+
+        // Set the subject
+        StringBuilder subject = new StringBuilder();
+        if (debug) {
+            subject.append("[sent from ").append(applicationHostname).append("] ");
+        }
+        subject.append("Comment on ").append(gadgetComment.getGadget().getTitle());
+        if (isUpdatedComment) {
+            subject.append(" - Updated");
+            if (gadgetComment.isLastModifiedByAdmin()) {
+                subject.append(" by Admin");
+            }
+        }
+
+        helper.setSubject(subject.toString());
+
+        // Add objects to the model
+        model.put("gadgetComment", gadgetComment);
+        model.put("user", user);
+        model.put("isUpdatedComment", isUpdatedComment);
+
+        //TODO: This doesnt work for https sites
+        StringBuilder linkToGadgetComments = new StringBuilder().append("http://")
+                .append(applicationHostname);
+        if (applicationPort != 80) {
+            linkToGadgetComments.append(":").append(applicationPort);
+        }
+        linkToGadgetComments.append(applicationContextPath)
+                .append("/app/repository/gadgetDetail?gadgetId=")
+                .append(gadgetComment.getGadget().getGadgetId())
+                .append("#addcomment");
+        model.put("linkToGadgetComments", linkToGadgetComments.toString());
+
+        // Set the text to the Freemarker-prepared message, using the appropriate template
+        helper.setText(prepareText(FM_GADGET_COMMENT, model), sendAsHtml);
+        return helper;
+    }
+
+    /**
+     * Get a MimeMessageHelper with some from address
+     *
+     * @return a MimeMessageHelper
+     * @throws MessagingException if there is an error setting up the MimeMessage
+     */
+    private MimeMessageHelper getMimeMessageHelper() throws MessagingException {
+        // First create the mail message and get a helper object for it
+        MimeMessage message = mailSender.createMimeMessage();
+        MimeMessageHelper helper = new MimeMessageHelper(message);
+
+        // Set the From
+        try {
+            helper.setFrom(fromAddress, FROM_ADDRESS_NAME);
+        } catch (UnsupportedEncodingException e) {
+            helper.setFrom(fromAddress);
+        }
+
+        return helper;
+    }
+
+    /**
+     * Prepares the text using the passed in model and the Freemarker template corresponding to the passed in name.
+     *
+     * @param fmName the name of the Freemarker template to use
+     * @param model  the model to be used by the Freemarker template
+     * @return the String result after Freemarker prepares the text from the template
+     * @throws javax.mail.MessagingException
+     */
+    private String prepareText(String fmName, Map<String, Object> model) throws MessagingException {
+        try {
+            return FreeMarkerTemplateUtils.processTemplateIntoString(getFreemarkerTemplate(fmName), model);
+        } catch (Exception e) {
+            throw new MessagingException(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * Sets the recipients as requested.  If in debug mode, doesn't actually set the To or CC, but instead
+     * includes that info as part of the message and sets the TO field to the debug address.
+     *
+     * @param tos    the email TO recipients
+     * @param helper the MimeMessageHelper
+     * @param model  the model to be passed on to Freemarker
+     * @throws MessagingException if there is an error setting the recipients on the MimeMessage
+     */
+    private void setRecipients(List<String> tos, MimeMessageHelper helper, Map<String, Object> model) throws MessagingException {
+        if (tos == null) {
+            tos = new ArrayList<String>();
+        }
+
+        // Set the to depending on if debug is on
+        if (debug) {
+            helper.setTo(debugAddress);
+            StringBuilder info = new StringBuilder();
+            info.append("TO: ");
+            for (String to : tos) {
+                info.append(to).append(" ");
+            }
+            model.put("debug", info);
+        } else {
+            for (String to : tos) {
+                helper.addTo(to);
+            }
+        }
+    }
+
+    private Template getFreemarkerTemplate(String templateName) throws IOException {
+        return freemarkerConfigurer.getConfiguration().getTemplate(templateName);
+    }
+
+}
\ No newline at end of file

Propchange: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/impl/FreemarkerEmailService.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/util/MetricsLoggingKeys.java
URL: http://svn.apache.org/viewvc/incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/util/MetricsLoggingKeys.java?rev=1087796&view=auto
==============================================================================
--- incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/util/MetricsLoggingKeys.java (added)
+++ incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/util/MetricsLoggingKeys.java Fri Apr  1 16:42:22 2011
@@ -0,0 +1,44 @@
+/*
+ * 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.mitre.portal.service.util;
+
+/**
+ * Class to hold static metrics logging key names
+ * 
+ * @author ACARLUCCI
+ */
+public class MetricsLoggingKeys {
+
+    public static enum GadgetActions {
+        ADD("addGadget"),
+        MOVE("moveGadget"),
+        DELETE("deleteGadget");
+
+        private final String dataType;
+        private GadgetActions(String dataType) {
+            this.dataType = dataType;
+        }
+
+        @Override
+        public String toString() {
+            return dataType;
+        }
+    }
+}

Propchange: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/util/MetricsLoggingKeys.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/util/PostMethodFactory.java
URL: http://svn.apache.org/viewvc/incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/util/PostMethodFactory.java?rev=1087796&view=auto
==============================================================================
--- incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/util/PostMethodFactory.java (added)
+++ incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/util/PostMethodFactory.java Fri Apr  1 16:42:22 2011
@@ -0,0 +1,37 @@
+/*
+ * 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.mitre.portal.service.util;
+
+import java.io.UnsupportedEncodingException;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+
+/**
+ *
+ * @author ACARLUCCI
+ */
+public class PostMethodFactory {
+    public PostMethod getInstance(String url, String content, String contentType, String charset) throws UnsupportedEncodingException {
+        PostMethod post = new PostMethod(url);
+        post.setRequestEntity(new StringRequestEntity(content, contentType, charset));
+        return post;
+    }
+
+}

Propchange: incubator/rave/donations/mitre-osec/src/org/mitre/portal/service/util/PostMethodFactory.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/rave/donations/mitre-osec/src/org/mitre/portal/web/controller/AdminController.java
URL: http://svn.apache.org/viewvc/incubator/rave/donations/mitre-osec/src/org/mitre/portal/web/controller/AdminController.java?rev=1087796&view=auto
==============================================================================
--- incubator/rave/donations/mitre-osec/src/org/mitre/portal/web/controller/AdminController.java (added)
+++ incubator/rave/donations/mitre-osec/src/org/mitre/portal/web/controller/AdminController.java Fri Apr  1 16:42:22 2011
@@ -0,0 +1,219 @@
+/*
+ * 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.mitre.portal.web.controller;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mitre.portal.model.*;
+import org.mitre.portal.service.GadgetService;
+import org.mitre.portal.service.exception.GadgetAudienceNotFoundException;
+import org.mitre.portal.service.exception.UnknownGadgetException;
+import org.mitre.portal.web.util.ModelKeys;
+import org.mitre.portal.web.util.ViewNames;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author ACARLUCCI
+ */
+@Controller
+@RequestMapping(value = "/admin/*")
+public class AdminController {
+    private final Log log = LogFactory.getLog(AdminController.class);
+
+    private final Container container;
+    private final GadgetService gadgetService;
+
+    @Autowired
+    public AdminController(Container container, GadgetService gadgetService) {
+        this.container = container;
+        this.gadgetService = gadgetService;
+    }
+
+    @RequestMapping(value = "home", method = RequestMethod.GET)
+    public String home(Model model) {
+        log.debug("viewing main admin page");
+        model.addAttribute(ModelKeys.CONTAINER, container);
+
+        return ViewNames.Admin.HOME;
+    }
+
+    @RequestMapping(value = "viewGadgetAudience", method = RequestMethod.GET)
+    public String viewGadgetAudience(Model model) {
+        log.debug("getting all gadgetAudiences");
+        model.addAttribute(ModelKeys.CONTAINER, container);
+        model.addAttribute(ModelKeys.GADGET_AUDIENCE_LIST, gadgetService.getAllAudiences());
+
+        return ViewNames.Admin.GADGET_AUDIENCE;
+    }
+
+    @RequestMapping(value = "saveGadgetAudience", method = RequestMethod.POST)
+    public String saveGadgetAudience(@RequestParam(value = "gadgetAudienceId") Long gadgetAudienceId,
+                                     @RequestParam(value = "code") String code,
+                                     @RequestParam(value = "description") String description,
+                                     Model model) throws GadgetAudienceNotFoundException {
+
+        GadgetAudience ga = new GadgetAudience();
+        if (gadgetAudienceId > 0) {
+            ga.setGadgetAudienceId(gadgetAudienceId);
+        }
+        ga.setCode(code);
+        ga.setDescription(description);
+
+        gadgetService.save(ga);
+
+        // send a browser redirect to the view controller so the browser's url changes
+        // this will prevent a browser refresh from re-invoking this controller
+        // and causing an error
+        return "redirect:viewGadgetAudience";
+    }
+
+    @RequestMapping(value = "deleteGadgetAudience", method = RequestMethod.POST)
+    public String deleteGadgetAudience(@RequestParam(value = "gadgetAudienceId") Long gadgetAudienceId,
+                                       Model model) throws GadgetAudienceNotFoundException {
+
+        GadgetAudience ga = gadgetService.getGadgetAudience(gadgetAudienceId);
+        gadgetService.delete(ga);
+
+        // send a browser redirect to the view controller so the browser's url changes
+        // this will prevent a browser refresh from re-invoking this controller
+        // and causing an error
+        return "redirect:viewGadgetAudience";
+    }
+
+
+    @RequestMapping(value = "viewSecurityUserRole", method = RequestMethod.GET)
+    public String viewSecurityUserRole(@RequestParam(value = "securityRoleUserId", required = false) String userId,
+                                       Model model) {
+        model.addAttribute(ModelKeys.CONTAINER, container);
+        model.addAttribute(ModelKeys.SECURITY_ROLES_LIST, gadgetService.getAllSecurityRoles());
+
+        // Set up a dummy userid (0) for the initial view
+        if (null == userId)
+            userId = "0";
+
+        model.addAttribute(ModelKeys.SECURITY_USER_ROLE_LIST, gadgetService.getAllSecurityUserRoleByUserId(userId));
+        model.addAttribute(ModelKeys.SECURITY_USER_ROLE_USER_ID, userId);
+
+        return ViewNames.Admin.SECURITY_USER_ROLE;
+    }
+
+
+    @RequestMapping(value = "getSecurityUserRoleByUser", method = RequestMethod.POST)
+    public String getSecurityUserRoleByUser(@RequestParam(value = "userId") String userId,
+                                            Model model) {
+        model.addAttribute(ModelKeys.CONTAINER, container);
+        model.addAttribute(ModelKeys.SECURITY_USER_ROLE_LIST, gadgetService.getAllSecurityUserRoleByUserId(userId));
+        model.addAttribute(ModelKeys.SECURITY_ROLES_LIST, gadgetService.getAllSecurityRoles());
+        model.addAttribute(ModelKeys.SECURITY_USER_ROLE_USER_ID, userId);
+        return ViewNames.Admin.SECURITY_USER_ROLE;
+    }
+
+
+    @RequestMapping(value = "setSecurityUserRoleForUser", method = RequestMethod.POST)
+    public String setSecurityUserRoleForUser(@RequestParam(value = "securityRoleUserId") String userId,
+                                             @RequestParam(value = "userSecurityRoles", required = false) String[] userSecurityRoles,
+                                             Model model) {
+        List<SecurityUserRole> currentSecurityUserRole = gadgetService.getAllSecurityUserRoleByUserId(userId);
+
+        // Delete the existing roles and we can recreate the rolws again
+        for (SecurityUserRole role : currentSecurityUserRole) {
+            gadgetService.delete(role);
+        }
+        SecurityUserRole securityUserRole = null;
+
+        if (userSecurityRoles != null && userSecurityRoles.length > 0) {
+            for (int i = 0; i < userSecurityRoles.length; i++) {
+                securityUserRole = new SecurityUserRole();
+                securityUserRole.setUserId(userId);
+                securityUserRole.setSecurityRoleName(userSecurityRoles[i]);
+                gadgetService.save(securityUserRole);
+            }
+        }
+
+        model.addAttribute(ModelKeys.SECURITY_USER_ROLE_USER_ID, userId);
+
+        // send a browser redirect to the view controller so the browser's url changes
+        // this will prevent a browser refresh from re-invoking this controller
+        // and causing an error
+        return "redirect:viewSecurityUserRole";
+    }
+
+    @RequestMapping(value = "refreshUserPrefsFromSpec", method = RequestMethod.GET)
+    public String refreshUserPrefsFromSpecView(Model model) {
+        return ViewNames.Admin.REFRESH_GADGETS;
+    }
+
+    @RequestMapping(value = "refreshUserPrefsFromSpec", method = RequestMethod.POST)
+    public String refreshUserPrefsFromSpec(Model model) {
+        List<String> results = new ArrayList<String>();
+        for (ContainerRegistry registry : container.getContainerRegistryList()) {
+            results.add(updateGadgetUserPrefs(registry));
+        }
+        model.addAttribute(ModelKeys.JSON_RESULT, results);
+        return ViewNames.JSON;
+    }
+
+    /**
+     * Catches any exceptions thrown by the doUpdate method and returns results accordingly
+     * @param registry container registry to retrieve gadget from
+     * @return the result of the operation
+     */
+    private String updateGadgetUserPrefs(ContainerRegistry registry) {
+        String result;
+        try {
+            result = doUpdateGadgetUserPrefs(registry);
+        } catch (Exception e) {
+            result = "Failed to update gadget " + registry.getGadget().getGadgetId() + " from " + registry.getGadget().getUrl() + ". Error: " + e.getMessage();
+            log.error(e);
+        }
+        return result;
+    }
+
+    /**
+     * Performs the update of gadget user prefs
+     * @param registry the container registry to retrieve gadget from
+     * @return the result of the operation
+     */
+    private String doUpdateGadgetUserPrefs(ContainerRegistry registry) throws GadgetAudienceNotFoundException, UnknownGadgetException {
+        String result;
+        URL specUrl = registry.getGadget().getUrl();
+        Gadget remoteGadget = gadgetService.findGadgetFromUrl(specUrl, container);
+
+        if (remoteGadget != null) {
+            gadgetService.updateUserPrefMetaData(registry.getGadget(), remoteGadget);
+            gadgetService.save(registry.getGadget());
+            result = "Successfully updated gadget " + registry.getGadget().getGadgetId() + " from " + specUrl;
+        } else {
+            result = "Failed to update gadget " + registry.getGadget().getGadgetId() + ". Gadget Spec no longer exists at " + specUrl;
+            log.warn("Gadget Spec no longer exists at " + specUrl);
+        }
+        return result;
+    }
+
+}

Propchange: incubator/rave/donations/mitre-osec/src/org/mitre/portal/web/controller/AdminController.java
------------------------------------------------------------------------------
    svn:executable = *