Marketplace servlet initial progress

Initial progress towards a Servlet view on Marketplace.  Cf. [UP-4080](https://issues.jasig.org/browse/UP-4080) (Marketplace Servlet "epic").

Partial progress
=============

This is an initial proof of concept proposed for merged *into a feature branch* for collaboration and continued work, *not yet proposed for merge to master* because it is so very much not baked.

You should not adopt in production this functionality as it is here implemented.

Context and Vision
===============

Where we're really trying to go here:
* compelling views on Marketplace suitable for Google search indexing and discovery via Google search
* somewhat inspired by https://one.iu.edu/ .

We're actually shockingly close to being able to deliver an experience like https://one.iu.edu/ as *one view on*, *one way of accessing* uPortal.  Personally, I (@apetro) don't think a Marketplace is the only way to navigate portal content, but I do think it's one way, and this feature branch is about making that possible in uPortal.  This is just the first increment of progress on the `marketplace_servlet_feature` branch.  Hang on to your seats, it's going to be a great ride.

Features
=======

Marketplace servlet view: responsive!
------------------------------------------------

A Servlet view on Marketplace renders, and it's even responsive.

![marketplace_servlet_admin_narrow](https://cloud.githubusercontent.com/assets/952283/2842677/4a485c52-d077-11e3-9702-7c5421aed44c.png)


Categories show
----------------------

Categories and portlets show, even filtered according to the user's `BROWSE` permission.

![marketplace_servlet_admin_categories](https://cloud.githubusercontent.com/assets/952283/2842678/5015aa86-d077-11e3-8663-d31117378340.png)


Marketplace entries render
-----------------------------------

Complete with screenshots, etc.

![marketplace_servlet_marketplace_entry](https://cloud.githubusercontent.com/assets/952283/2842680/549662b2-d077-11e3-8e8e-318f403525df.png)



At a pretty URL
---------------------------------------

Marketplace entries are addressed as a path element.  Very hipster.

![marketplace_servlet_xkcd_entry](https://cloud.githubusercontent.com/assets/952283/2842682/5acfe0f4-d077-11e3-9516-adf54931d893.png)

Filtering works
-------------------

Yay Datatables / JavaScript (but boo the brute force I'm doing to include the necessary dependencies!)

![marketplace_servlet_filters_mark](https://cloud.githubusercontent.com/assets/952283/2842692/750acac4-d077-11e3-9c3c-90ccae6662d1.png)


Works even when not logged in
----------------------------------------

Respects permissions of logged-in-user or of `guest` if not logged in.  Just works.


Implementation thoughts
====================

Arguably this could have been a usage of the `DETACHED` portlet mode on the existing Marketplace portlet instead, but 
* Servlet views on uPortal need exploring
* This is a step towards making the Marketplace service re-usable by being re-used, and so a step towards JSON APIs (and eventually All The Things will be JavaScript rendering JSON APIs!)
* Servlet controller and view gives a lot more control about URL structure and markup towards the goal of search engine indexability.

Known shortcomings and technical debt
================================

This just ain't baked.  Proof-of-concept-deep only.

Unmaintainable horrible brute force styling
------------------------------------------------------

This changeset takes the brute force approach of providing styling to the servlet JSPs, but doesn't use a CDN or ResourceServer appropriately and doesn't respect skin customizations and basically what it's doing is an unacceptable brute force first pass to prove the concept that these JSPs can work.  Backlogged as [UP-4081](https://issues.jasig.org/browse/UP-4081).

Links don't work
---------------------
(Almost) none of the hyperlinks work in the servlet views, their having been de-featured to get to inital proof-of-concept rendering.  That's both navigational links and action links.  (Backlogged as [UP-4082](https://issues.jasig.org/browse/UP-4082).

The UI doesn't gracefully degrade to reflect permissions on those links that don't render (as in, it doesn't even try to suppress the favorite/go link if you don't have permission to subscribe the portlet).  Backlogged as [UP-4083](https://issues.jasig.org/browse/UP-4083).

Abusing /api namespace
--------------------------------

The Servlet view on Marketplace isn't an `/api`, but it's at the `/api` path since I'm abusing the mvcController that runs the existing `/api` JSON APIs.  Better would be to invent a `/web` path or so for shiny new Servlet views on uPortal stuff.

I took a stab at adding a parallel MVC controller to implement `/web` and I'm embarrassed to say I couldn't figure it out in an appropriate timebox, so, backlogged as [UP-4084](https://issues.jasig.org/browse/UP-4084).

Also, addressing as `/api/marketplace/` works, but `/api/marketplace` doesn't, and that'll really annoy you when you trip over it! (Also backlogged in [UP-4084](https://issues.jasig.org/browse/UP-4084).

Abstraction violations and duplication
-----------------------------------------------

While this benefits from some refactoring of Marketplace functionality into a service layer, the Controllers still directly depend on DAOs when really they should be going through the Service layer for that, and refactoring to that architecture will allow further de-duplication of functionality across the servlet and portlet Controllers over this functionality. Backlogged as [UP-4085](https://issues.jasig.org/browse/UP-4085).

No consideration of performance
------------------------------------------

Still ain't got no caching. :)  That's backlogged as [UP-4072](https://issues.jasig.org/browse/UP-4072).  In practice if you let a search engine crawl this as is, it would probably beat the heck out of your portal.

Category BROWSE permission not reflected in Marketplace entry view
-----------------------------------------------------------------------------------------

Marketplace entries don't filter out Categories that the user doesn't have permission to `BROWSE`.  Backlogged as [UP-4086](https://issues.jasig.org/browse/UP-4086).