← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 13601: extended AppController so that it can serve apps, useful for debugging/development of new apps. A...

 

------------------------------------------------------------
revno: 13601
committer: Morten Olav Hansen <mortenoh@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2014-01-07 10:55:49 +0100
message:
  extended AppController so that it can serve apps, useful for debugging/development of new apps. Apps can be reached by /api/apps/app-name/, no caching, so should not be used for prod (but you can set the internal app path to this location if you want for testing).
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/appmanager/AppManager.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AppController.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/appmanager/AppManager.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/appmanager/AppManager.java	2013-10-22 15:02:04 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/appmanager/AppManager.java	2014-01-07 09:55:49 +0000
@@ -39,69 +39,78 @@
 {
     final String ID = AppManager.class.getName();
 
-    final String KEY_APP_FOLDER_PATH = "appFolderPath";    
+    final String KEY_APP_FOLDER_PATH = "appFolderPath";
     final String KEY_APP_BASE_URL = "appBaseUrl";
     final String KEY_APP_STORE_URL = "appStoreUrl";
     final String DEFAULT_APP_STORE_URL = "http://appstore.dhis2.org";;
-        
+
     /**
      * Gets the Base URL for accessing the apps
+     *
      * @return the apps baseurl
      */
     String getAppBaseUrl();
-    
+
     /**
      * Returns the full path to the folder where apps are extracted
-     * @return app folder path 
+     *
+     * @return app folder path
      */
     String getAppFolderPath();
 
     /**
      * Returns the url of the app repository
-     * @return url of appstore 
+     *
+     * @return url of appstore
      */
     String getAppStoreUrl();
 
     /**
      * Returns a list of all the installed apps at @see getAppFolderPath
+     *
      * @return list of installed apps
      */
     List<App> getApps();
-    
+
     /**
      * Installs the app.
-     * @param file the app file.
+     *
+     * @param file     the app file.
      * @param fileName the name of the app file.
      * @param rootPath the root path of the instance.
      * @throws IOException if the app manifest file could not be read.
      */
     void installApp( File file, String fileName, String rootPath )
         throws IOException;
-    
+
     /**
      * Deletes the app with the given name.
+     *
      * @param name the app name.
      * @return true if the delete was successful, false if there is no app with
-     *         the given name or if the app could not be removed from the file
-     *         system.
+     * the given name or if the app could not be removed from the file
+     * system.
      */
     boolean deleteApp( String name );
 
     /**
-     * Saves the folder in which apps will be expanded 
+     * Saves the folder in which apps will be expanded
+     *
      * @param appFolderPath
      */
     void setAppFolderPath( String appFolderPath );
 
     /**
      * Saves the URL of the apps repository
+     *
      * @param appStoreUrl
      */
     void setAppStoreUrl( String appStoreUrl );
-    
+
     /**
      * Saves the base URL where apps are installed
-     * @param appBaseUrl 
+     *
+     * @param appBaseUrl
      */
     void setAppBaseUrl( String appBaseUrl );
 }

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AppController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AppController.java	2013-10-22 15:02:04 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AppController.java	2014-01-07 09:55:49 +0000
@@ -28,35 +28,117 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import java.util.List;
-
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.google.common.collect.Lists;
+import org.hisp.dhis.api.controller.exception.NotFoundException;
 import org.hisp.dhis.appmanager.App;
 import org.hisp.dhis.appmanager.AppManager;
+import org.hisp.dhis.dxf2.utils.JacksonUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
+import org.springframework.util.StreamUtils;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * @author Lars Helge Overland
  */
 @Controller
-@RequestMapping( value = AppController.RESOURCE_PATH )
 public class AppController
 {
     public static final String RESOURCE_PATH = "/apps";
-    
+
     @Autowired
     private AppManager appManager;
-    
-    @RequestMapping( method = RequestMethod.GET )
+
+    private ResourceLoader resourceLoader = new DefaultResourceLoader();
+
+    @RequestMapping( value = RESOURCE_PATH, method = RequestMethod.GET )
     public String getApps( Model model )
     {
         List<App> apps = appManager.getApps();
-        
+
         model.addAttribute( "model", apps );
-        
+
         return "apps";
     }
+
+    @RequestMapping( value = "/apps/{app}/**", method = RequestMethod.GET )
+    public void renderApp( @PathVariable( "app" ) String app, HttpServletRequest request, HttpServletResponse response ) throws IOException, NotFoundException
+    {
+        Iterable<Resource> locations = Lists.newArrayList(
+            resourceLoader.getResource( "file:" + appManager.getAppFolderPath() + "/" + app + "/" ),
+            resourceLoader.getResource( "classpath*:/apps/" + app + "/" )
+        );
+
+        Resource manifest = findResource( locations, "manifest.webapp" );
+
+        if ( manifest == null )
+        {
+            throw new NotFoundException();
+        }
+
+        Map<String, Object> manifestMap = JacksonUtils.getJsonMapper().readValue( manifest.getInputStream(), new TypeReference<HashMap<String, Object>>()
+        {
+        } );
+
+        String defaultPage = (String) manifestMap.get( "launch_path" );
+        String pageName = findPage( request.getPathInfo(), app );
+
+        Resource page = findResource( locations, pageName );
+
+        if ( page == null )
+        {
+            page = findResource( locations, defaultPage );
+
+            if ( page == null )
+            {
+                throw new NotFoundException();
+            }
+        }
+
+        String mimeType = request.getSession().getServletContext().getMimeType( page.getFilename() );
+        response.setContentType( mimeType );
+
+        StreamUtils.copy( page.getInputStream(), response.getOutputStream() );
+    }
+
+    private Resource findResource( Iterable<Resource> locations, String resourceName ) throws IOException
+    {
+        for ( Resource location : locations )
+        {
+            Resource resource = location.createRelative( resourceName );
+
+            if ( resource.exists() && resource.isReadable() )
+            {
+                return resource;
+            }
+        }
+
+        return null;
+    }
+
+    private String findPage( String path, String app )
+    {
+        String prefix = RESOURCE_PATH + "/" + app + "/";
+
+        if ( path.startsWith( prefix ) )
+        {
+            path = path.substring( prefix.length() );
+        }
+
+        return path;
+    }
 }