-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathHomeController.groovy
291 lines (244 loc) · 11 KB
/
HomeController.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
package au.org.ala.merit
import au.org.ala.merit.hub.HubSettings
import grails.converters.JSON
import grails.core.GrailsApplication
import org.apache.commons.lang.StringUtils
import javax.servlet.http.Cookie
import java.text.SimpleDateFormat
class HomeController {
def projectService
def searchService
def settingService
def metadataService
def userService
def reportService
def documentService
def statisticsFactory
def blogService
def commonService
ActivityService activityService
GrailsApplication grailsApplication
/** Cookie issued by the ALA authentication system that indicates an SSO session may be available*/
static final String ALA_AUTH = "ALA-Auth"
/** This facet is used by name to filter the list of activity types available for download selection */
static final String ACTIVITY_TYPE_FACET_NAME = 'activities.type.keyword'
static final DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy")
def index() {
HubSettings hubSettings = SettingService.hubConfig
if (hubSettings.overridesHomePage()) {
forward(hubSettings.getHomePageControllerAndAction())
return
}
publicHome()
}
/**
* When we press the login button, the CAS service URL will point at this action, which is a protected path
* which ensures the CAS ticket validation filter consumes the service ticket.
* We then just redirect back to the homepage
*/
def login() {
Cookie[] cookies = request.getCookies()
boolean found = false
for (Cookie cookie:cookies) {
if (cookie.name == ALA_AUTH) {
found = true
}
}
if (!found) {
Cookie alaAuth = createAlaCookie()
response.addCookie(alaAuth)
}
redirect(url:grailsApplication.config.getProperty('grails.serverURL'))
}
/** The CAS session & ALA cookies can get out of sync, this puts them back in sync */
private Cookie createAlaCookie() {
// Don't want the cookie secure in dev environments as HTTPS is generally not used.
boolean useSecureCookie = grailsApplication.config.getProperty('server.servlet.session.cookie.secure', Boolean, false)
Cookie alaAuth = new Cookie(ALA_AUTH, userService.getUser().userName)
alaAuth.setDomain("ala.org.au")
alaAuth.setPath("/")
alaAuth.setHttpOnly(true)
alaAuth.setSecure(useSecureCookie)
alaAuth
}
def projectExplorer() {
def model = projectExplorerModel()
render view:'index', model:model
}
def ajaxProjectExplorer() {
render template: 'projectFinder', model:projectExplorerModel(), layout: 'ajax'
}
private Map projectExplorerModel() {
def facetsList = new ArrayList(SettingService.getHubConfig().availableFacets ?:[])
def mapFacets = new ArrayList(SettingService.getHubConfig().availableMapFacets ?: [])
boolean canViewAdminFacets = userService.userIsAlaOrFcAdmin() || userService.userHasReadOnlyAccess()
if (!canViewAdminFacets) {
List adminFacetList = SettingService.getHubConfig().adminFacets ?: []
facetsList?.removeAll(adminFacetList)
mapFacets?.removeAll(adminFacetList)
}
boolean canViewDownloads = canViewAdminFacets || userService.userIsSiteAdmin()
boolean canViewOfficerFacets = userService.userIsSiteAdmin() || userService.userHasReadOnlyAccess()
if (!canViewOfficerFacets) {
List officerFacetList = SettingService.getHubConfig().officerFacets ?: []
facetsList?.removeAll(officerFacetList)
mapFacets?.removeAll(officerFacetList)
}
def fqList = params.getList('fq')
def allFacets = fqList + (SettingService.getHubConfig().defaultFacetQuery?:[])
def selectedGeographicFacets = findSelectedGeographicFacets(allFacets)
def resp = searchService.HomePageFacets(params)
def model = [
facetsList: facetsList,
mapFacets: mapFacets,
geographicFacets:selectedGeographicFacets,
description: settingService.getSettingText(SettingPageType.DESCRIPTION),
results: resp,
projectCount: resp?.hits?.total ?: 0,
includeDownloads: canViewDownloads
]
if (canViewAdminFacets) {
List activityTypes = metadataService.activityTypesList()
Map activityTypesFacet = resp?.facets?.get(ACTIVITY_TYPE_FACET_NAME)
model.activityTypes = filterActivityTypesToProjectSelection(activityTypes, activityTypesFacet)
}
model
}
/**
* If the activity type facet is available, only make those activities available for
* download that match the selected projects.
* @param allActivityTypes all available activity types
* @param activityTypesFacet the results of the search query containing only those activity types
* that are associated with a selected project.
*/
private List filterActivityTypesToProjectSelection(List allActivityTypes, Map activityTypesFacet) {
List filteredActivityTypes = allActivityTypes
if (activityTypesFacet) {
filteredActivityTypes = []
List selectableActivityTypes = activityTypesFacet?.terms?.collect{it.term}
List emsaFormNames = activityService.monitoringProtocolForms()?.collect{it.name}
if (emsaFormNames) {
selectableActivityTypes.removeAll(emsaFormNames)
}
allActivityTypes.each {
List matchingTypes = it.list?.findAll{it.name in selectableActivityTypes}
if (matchingTypes) {
filteredActivityTypes << [name:it.name, list:matchingTypes]
}
}
}
filteredActivityTypes
}
def publicHome() {
String expiryDateDisplay = session.getAttribute(LoginRecordingInterceptor.EXPIRY_DATE) ?: null
def statistics = statisticsFactory.randomGroup(session.lastGroup ?: -1)
session.lastGroup = statistics.group // So we can request more stats and not get 2 in a row the same
def images = reportService.homePageImages()
def helpPage = g.createLink([action:'help'])
def helpLinks = documentService.findAllHelpResources()
List copyOfLinks = new ArrayList(helpLinks) // The result of the call is cached so we don't want to add elements to it.
copyOfLinks << [name:'MORE RESOURCES', type:'', url:helpPage]
def blog = blogService.getSiteBlog()
def model = [statistics:statistics.statistics, helpLinks:copyOfLinks, images:images, blog:blog, expiryDate: expiryDateDisplay]
if (params.fq) {
model.putAll(projectExplorerModel())
model.showProjectExplorer = true
}
render view:'public', model:model
}
/**
* The purpose of this method is to enable the display of the spatial object corresponding to a selected
* value from a geographic facet (e.g. to display the polygon representing NSW on the map if the user has
* selected NSW from the "state" facet list.
*
* First we check to see if we have a geographic facet configuration for any of the user's facet selections.
* If so, we find the spatial object configuration matching the selected value and add that to the returned
* model. The selected polygon can then be requested by PID from geoserver.
*
* By convention, the facet field names in the search index have a suffix of "Facet" whereas the facet configuration
* doesn't include the word "Facet" (although maybe it should).
*/
private ArrayList findSelectedGeographicFacets(Collection allFacets) {
def facetConfig = metadataService.getGeographicFacetConfig()
def selectedGeographicFacets = []
allFacets.each { facet ->
def token = facet.split(':')
if(token.size() == 2){
def matchingFacet = facetConfig.find { token[0].startsWith(it.key) }
if (matchingFacet) {
def matchingValue = matchingFacet.value.find { it.key == token[1] }
if (matchingValue) {
selectedGeographicFacets << matchingValue.value
}
}
}
}
selectedGeographicFacets
}
def tabbed() {
[geoPoints: searchService.allGeoPoints(params)]
}
def geoService() {
params.max = params.max?:9999
if(params.geo){
params.facets = StringUtils.join(SettingService.getHubConfig().availableFacets, ',')
boolean reducePrecision = params.getBoolean('heatmap')
Map geoData = searchService.allProjectsWithSites(params, null, reducePrecision)
render geoData as JSON
} else {
if (userService.userIsAlaOrFcAdmin()){
params.include = ['name', 'managementUnitName', 'managementUnitId', 'programId', 'description', 'associatedProgram', 'associatedSubProgram','lastUpdated',
'funding', 'associatedOrgs', 'externalId', 'plannedEndDate', 'plannedStartDate', 'activities.siteId','activities.type','sites.siteId', 'sites.projects', 'sites.extent.geometry']
} else {
params.include = ['name', 'description', 'lastUpdated', 'associatedOrgs', 'managementUnitName','managementUnitId', 'programId', 'associatedProgram', 'associatedSubProgram']
}
Map resp = searchService.allProjects(params)
render resp as JSON
}
}
def getProjectsForIds() {
render searchService.getProjectsForIds(params) as JSON
}
def myProfile() {
redirect(controller: 'user')
}
def about() {
renderStaticPage(SettingPageType.ABOUT, true)
}
def help() {
renderStaticPage(SettingPageType.HELP, false)
}
def contacts() {
renderStaticPage(SettingPageType.CONTACTS, false)
}
/**
* Returns a small amount of javascript to let other tabs know the user has been logged back in
* and closes the tab.
*/
def close() {
response.setContentType("text/html")
render """<html><head><script type="text/javascript">
localStorage.setItem('login', new Date());
window.close();
</script></head><body/></html>"""
}
def staticPage(String id) {
def settingType = SettingPageType.getForName(id)
if (settingType) {
renderStaticPage(settingType)
} else {
response.sendError(404)
return
}
}
def i18n() {
if (request.isGet()) {
Map props = commonService.i18n(request.locale)
render props as JSON
}
}
private renderStaticPage(SettingPageType settingType, showNews = false) {
def content = settingService.getSettingText(settingType)
render view: 'about', model: [settingType: settingType, content: content, showNews: showNews]
}
}