Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Genesys PGR
Genesys Backend
Commits
1dea75f5
Commit
1dea75f5
authored
Oct 27, 2017
by
Matija Obreza
Browse files
Beanshell admin tool
parent
cfd309b6
Changes
5
Hide whitespace changes
Inline
Side-by-side
pom.xml
View file @
1dea75f5
...
...
@@ -537,6 +537,11 @@
<artifactId>
glis-client-resttemplate
</artifactId>
<version>
1.0-SNAPSHOT
</version>
</dependency>
<dependency>
<groupId>
org.apache-extras.beanshell
</groupId>
<artifactId>
bsh
</artifactId>
<version>
2.0b6
</version>
</dependency>
</dependencies>
<build>
...
...
src/main/java/org/genesys2/server/servlet/controller/admin/BeanshellController.java
0 → 100644
View file @
1dea75f5
/*
* Copyright 2017 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.genesys2.server.servlet.controller.admin
;
import
java.io.ByteArrayOutputStream
;
import
java.io.PrintStream
;
import
java.io.Reader
;
import
java.io.Serializable
;
import
java.util.HashMap
;
import
java.util.Map
;
import
javax.persistence.EntityManager
;
import
javax.persistence.PersistenceContext
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.SerializationFeature
;
import
org.genesys.glis.v1.api.GenesysApi
;
import
org.genesys2.server.service.GenesysFilterService
;
import
org.genesys2.server.service.GenesysService
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.jdbc.core.JdbcTemplate
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.ui.ModelMap
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.servlet.ModelAndView
;
import
org.springframework.web.servlet.mvc.support.RedirectAttributes
;
import
bsh.ConsoleInterface
;
import
bsh.EvalError
;
import
bsh.Interpreter
;
/**
* Beanshell
*
* @author Matija Obreza
*/
@Controller
@RequestMapping
(
"/admin/bsh"
)
@PreAuthorize
(
"hasRole('ADMINISTRATOR')"
)
public
class
BeanshellController
implements
InitializingBean
{
public
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
BeanshellController
.
class
);
@Autowired
private
GenesysService
genesysService
;
@Autowired
private
GenesysFilterService
filterService
;
@Autowired
private
GenesysApi
glisGenesys
;
@PersistenceContext
private
EntityManager
entityManager
;
@Autowired
private
JdbcTemplate
jdbcTemplate
;
private
ObjectMapper
mapper
;
private
Map
<
String
,
Object
>
exposedBeans
;
@Override
public
void
afterPropertiesSet
()
throws
Exception
{
mapper
=
new
ObjectMapper
();
mapper
.
disable
(
SerializationFeature
.
EAGER_SERIALIZER_FETCH
);
mapper
.
disable
(
SerializationFeature
.
FAIL_ON_EMPTY_BEANS
);
this
.
exposedBeans
=
new
HashMap
<>();
this
.
exposedBeans
.
put
(
"json"
,
mapper
);
this
.
exposedBeans
.
put
(
"genesysService"
,
genesysService
);
this
.
exposedBeans
.
put
(
"filterService"
,
filterService
);
this
.
exposedBeans
.
put
(
"glisGenesys"
,
glisGenesys
);
this
.
exposedBeans
.
put
(
"entityManager"
,
entityManager
);
this
.
exposedBeans
.
put
(
"jdbc"
,
jdbcTemplate
);
}
/**
* Render the form.
*/
@RequestMapping
(
method
=
RequestMethod
.
GET
)
public
ModelAndView
defaultView
(
ModelMap
model
)
{
model
.
addAttribute
(
"beans"
,
this
.
exposedBeans
);
return
new
ModelAndView
(
"/admin/beanshell"
,
model
);
}
/**
* Execute script in read-only transaction.
*
* @param model
* @param script
* @return
*/
@Transactional
(
readOnly
=
true
,
noRollbackFor
=
Exception
.
class
)
@RequestMapping
(
method
=
RequestMethod
.
POST
,
params
=
{
"readonly"
,
"script"
})
public
String
bshExecReadonly
(
RedirectAttributes
redirectAttributes
,
@RequestParam
(
name
=
"script"
)
String
script
)
{
LOG
.
debug
(
"Executing script in readonly mode\n{}"
,
script
);
return
executeScript
(
redirectAttributes
,
script
);
}
private
String
executeScript
(
RedirectAttributes
redirectAttributes
,
String
script
)
{
redirectAttributes
.
addFlashAttribute
(
"script"
,
script
);
try
{
ConsoleInterface
console
=
new
MemoryConsole
();
Interpreter
i
=
initializeInterpreter
(
console
);
Object
result
=
i
.
eval
(
script
);
redirectAttributes
.
addFlashAttribute
(
"result"
,
result
);
try
{
redirectAttributes
.
addFlashAttribute
(
"resultJson"
,
mapper
.
writerWithDefaultPrettyPrinter
().
writeValueAsString
(
result
));
}
catch
(
Throwable
e
)
{
redirectAttributes
.
addFlashAttribute
(
"resultJson"
,
"Could not convert to JSON: "
+
e
.
getMessage
());
}
redirectAttributes
.
addFlashAttribute
(
"console"
,
console
.
toString
());
}
catch
(
final
EvalError
e
)
{
LOG
.
error
(
e
.
getMessage
());
redirectAttributes
.
addFlashAttribute
(
"error"
,
new
BeanshellError
(
e
));
}
catch
(
final
Throwable
e
)
{
LOG
.
error
(
e
.
getMessage
(),
e
);
redirectAttributes
.
addFlashAttribute
(
"exception"
,
new
BeanshellError
(
e
));
}
return
"redirect:/admin/bsh"
;
}
protected
Interpreter
initializeInterpreter
(
ConsoleInterface
console
)
throws
EvalError
{
final
Interpreter
i
=
new
Interpreter
(
console
);
// beans
exposedBeans
.
entrySet
().
stream
().
forEach
(
entry
->
{
try
{
i
.
set
(
entry
.
getKey
(),
entry
.
getValue
());
}
catch
(
EvalError
e
)
{
LOG
.
error
(
"Trouble initializing bsh interpreter with key={}: {}"
,
entry
.
getKey
(),
e
.
getMessage
(),
e
);
}
});
// imports
i
.
eval
(
"import org.genesys2.server.model.genesys.*;"
);
return
i
;
}
/**
* Byte array backed Beanshell console
*/
public
static
class
MemoryConsole
implements
ConsoleInterface
{
private
final
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
(
1024
*
1024
);
private
final
PrintStream
stdout
=
new
PrintStream
(
baos
,
true
);
private
final
PrintStream
stderr
=
new
PrintStream
(
baos
,
true
);
@Override
public
Reader
getIn
()
{
return
null
;
}
@Override
public
PrintStream
getOut
()
{
return
stdout
;
}
@Override
public
PrintStream
getErr
()
{
return
stderr
;
}
@Override
public
void
println
(
Object
o
)
{
stdout
.
println
(
o
);
}
@Override
public
void
print
(
Object
o
)
{
stdout
.
print
(
o
);
}
@Override
public
void
error
(
Object
o
)
{
stderr
.
println
(
o
);
}
@Override
public
String
toString
()
{
return
baos
.
toString
();
}
}
/**
* Serializable exception wrapper for flash attributes
*/
public
static
class
BeanshellError
implements
Serializable
{
private
static
final
long
serialVersionUID
=
6436834633021529446L
;
private
String
message
;
private
StackTraceElement
[]
stackTrace
;
private
int
errorLineNumber
;
private
String
errorText
;
private
String
cause
;
private
String
scriptStackTrace
;
private
String
errorClass
;
public
BeanshellError
(
Throwable
e
)
{
this
.
errorClass
=
e
.
getClass
().
getName
();
this
.
message
=
e
.
getMessage
();
this
.
stackTrace
=
e
.
getStackTrace
();
if
(
e
instanceof
EvalError
)
{
EvalError
ee
=
(
EvalError
)
e
;
this
.
errorLineNumber
=
ee
.
getErrorLineNumber
();
this
.
errorText
=
ee
.
getErrorText
();
this
.
scriptStackTrace
=
ee
.
getScriptStackTrace
();
if
(
ee
.
getCause
()
!=
null
)
this
.
cause
=
ee
.
getCause
().
getMessage
();
}
}
public
String
getMessage
()
{
return
message
;
}
public
StackTraceElement
[]
getStackTrace
()
{
return
stackTrace
;
}
public
String
getCause
()
{
return
cause
;
}
public
int
getErrorLineNumber
()
{
return
errorLineNumber
;
}
public
String
getErrorText
()
{
return
errorText
;
}
public
String
getScriptStackTrace
()
{
return
scriptStackTrace
;
}
public
String
getErrorClass
()
{
return
errorClass
;
}
}
}
src/main/resources/content/language.properties
View file @
1dea75f5
...
...
@@ -749,6 +749,7 @@ menu.admin.repository=Repository
menu.admin.repository.files
=
Repository file manager
menu.admin.repository.galleries
=
Image galleries
menu.admin.hazelcast
=
Hazelcast
menu.admin.beanshell
=
Beanshell
news.content.page.all.title
=
News list
news.archive.title
=
News Archive
...
...
src/main/webapp/WEB-INF/decorator/1/admin.jsp
View file @
1dea75f5
...
...
@@ -3,171 +3,213 @@
<!DOCTYPE html>
<html
lang=
"${pageContext.response.locale.language}"
dir=
"${pageContext.response.locale.language=='fa' || pageContext.response.locale.language=='ar' ? 'rtl' : 'ltr'}"
class=
"genesys-page"
>
<head>
<title><sitemesh:write
property=
"title"
/></title>
<meta
charset=
"utf-8"
/>
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<meta
name=
"language"
content=
"${pageContext.response.locale.language}"
/>
<meta
name=
"robots"
content=
"noindex, nofollow"
/>
<!-- CSRF protection-->
<meta
name=
"_csrf"
content=
"${_csrf.token}"
/>
<!-- default header name is X-CSRF-TOKEN -->
<meta
name=
"_csrf_header"
content=
"${_csrf.headerName}"
/>
<!-- Links -->
<link
rel=
"shortcut icon"
href=
"
<c:url
value=
"
${
cdnServers
.
next
}
/html/1/images/genesys.png"
/>
"
/>
<!-- opensearch.org -->
<link
rel=
"search"
hreflang=
"${pageContext.response.locale.language}"
type=
"application/opensearchdescription+xml"
href=
"
<c:url
value=
"/acn/opensearch/desc"
/>
"
title=
"
<spring:message
code=
"search.input.placeholder"
/>
"
/>
<!-- l10n -->
<link
rel=
"alternate"
hreflang=
"en"
href=
"
<c:url
value=
"/en${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}"
/>
"
/>
<link
rel=
"alternate"
hreflang=
"ar"
href=
"
<c:url
value=
"/ar${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}"
/>
"
/>
<link
rel=
"alternate"
hreflang=
"de"
href=
"
<c:url
value=
"/de${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}"
/>
"
/>
<link
rel=
"alternate"
hreflang=
"es"
href=
"
<c:url
value=
"/es${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}"
/>
"
/>
<link
rel=
"alternate"
hreflang=
"fa"
href=
"
<c:url
value=
"/fa${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}"
/>
"
/>
<link
rel=
"alternate"
hreflang=
"fr"
href=
"
<c:url
value=
"/fr${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}"
/>
"
/>
<link
rel=
"alternate"
hreflang=
"pt"
href=
"
<c:url
value=
"/pt${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}"
/>
"
/>
<link
rel=
"alternate"
hreflang=
"ru"
href=
"
<c:url
value=
"/ru${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}"
/>
"
/>
<link
rel=
"alternate"
hreflang=
"zh"
href=
"
<c:url
value=
"/zh${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}"
/>
"
/>
<!-- Custom styles for this template -->
<%@ include
file=
"css.jsp"
%>
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<head>
<title><sitemesh:write
property=
"title"
/></title>
<meta
charset=
"utf-8"
/>
<meta
http-equiv=
"X-UA-Compatible"
content=
"IE=edge"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<meta
name=
"language"
content=
"${pageContext.response.locale.language}"
/>
<meta
name=
"robots"
content=
"noindex, nofollow"
/>
<!-- CSRF protection-->
<meta
name=
"_csrf"
content=
"${_csrf.token}"
/>
<!-- default header name is X-CSRF-TOKEN -->
<meta
name=
"_csrf_header"
content=
"${_csrf.headerName}"
/>
<!-- Links -->
<link
rel=
"shortcut icon"
href=
"
<c:url
value=
'
${
cdnServers
.
next
}
/html/1/images/genesys.png'
/>
"
/>
<!-- opensearch.org -->
<link
rel=
"search"
hreflang=
"${pageContext.response.locale.language}"
type=
"application/opensearchdescription+xml"
href=
"
<c:url
value=
'/acn/opensearch/desc'
/>
"
title=
"
<spring:message
code=
'search.input.placeholder'
/>
"
/>
<!-- l10n -->
<link
rel=
"alternate"
hreflang=
"en"
href=
"
<c:url
value=
'/en${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}'
/>
"
/>
<link
rel=
"alternate"
hreflang=
"ar"
href=
"
<c:url
value=
'/ar${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}'
/>
"
/>
<link
rel=
"alternate"
hreflang=
"de"
href=
"
<c:url
value=
'/de${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}'
/>
"
/>
<link
rel=
"alternate"
hreflang=
"es"
href=
"
<c:url
value=
'/es${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}'
/>
"
/>
<link
rel=
"alternate"
hreflang=
"fa"
href=
"
<c:url
value=
'/fa${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}'
/>
"
/>
<link
rel=
"alternate"
hreflang=
"fr"
href=
"
<c:url
value=
'/fr${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}'
/>
"
/>
<link
rel=
"alternate"
hreflang=
"pt"
href=
"
<c:url
value=
'/pt${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}'
/>
"
/>
<link
rel=
"alternate"
hreflang=
"ru"
href=
"
<c:url
value=
'/ru${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}'
/>
"
/>
<link
rel=
"alternate"
hreflang=
"zh"
href=
"
<c:url
value=
'/zh${pageContext.request.getAttribute('org.genesys2.server.servlet.filter.LocaleURLFilter.INTERNALURL')}'
/>
"
/>
<!-- Custom styles for this template -->
<%@ include
file=
"css.jsp"
%>
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<sitemesh:write
property=
"head"
/>
<meta
name=
"author"
content=
"Global Crop Diversity Trust"
/>
</head>
<security:authentication
var=
"user"
property=
"principal"
/>
<![endif]-->
<sitemesh:write
property=
"head"
/>
<meta
name=
"author"
content=
"Global Crop Diversity Trust"
/>
</head>
<security:authentication
var=
"user"
property=
"principal"
/>
<body>
<%@ include
file=
"header.jsp"
%>
<div
class=
"admin-page"
>
<nav
class=
"navbar navbar-default navbar-inverse navbar-fixed-top"
>
<div
class=
"container-fluid"
>
<div
class=
"navbar-header"
>
<button
type=
"button"
class=
"humburger-btn navbar-toggle collapsed pull-left"
data-toggle=
"collapse"
data-target=
"#navbar"
aria-expanded=
"false"
aria-controls=
"navbar"
>
<span
class=
"sr-only"
>
Toggle navigation
</span>
<span
class=
"icon-bar"
></span>
<span
class=
"icon-bar"
></span>
<span
class=
"icon-bar"
></span>
</button>
<%--<a class="navbar-brand" href="<c:url value='/admin/' />"> <spring:message code="page.home.title" /> </a>--%>
<a
class=
"navbar-brand nav-logo clearfix"
href=
"
<c:url
value=
'/admin/'
/>
"
><img
src=
"
<c:url
value=
'
${
cdnServers
.
next
}
/html/1/images/GENESYS-ICON.svg'
/>
"
/><img
src=
"/html/1/images/GENESYS-LOGO.svg"
/></a>
</div>
<div
id=
"navbar"
class=
"collapse navbar-collapse"
>
<div
class=
"col-md-7 col-lg-10 no-space"
>
<div
class=
"navbar-header"
>
<button
type=
"button"
class=
"humburger-btn navbar-toggle collapsed pull-left"
data-toggle=
"collapse"
data-target=
"#navbar"
aria-expanded=
"false"
aria-controls=
"navbar"
>
<span
class=
"sr-only"
>
Toggle navigation
</span>
<span
class=
"icon-bar"
></span>
<span
class=
"icon-bar"
></span>
<span
class=
"icon-bar"
></span>
</button>
<%--<a class="navbar-brand" href="<c:url value='/admin/' />"> <spring:message code="page.home.title" /> </a>--%>
<a
class=
"navbar-brand nav-logo clearfix"
href=
"
<c:url
value=
'/admin/'
/>
"
><img
src=
"
<c:url
value=
'
${
cdnServers
.
next
}
/html/1/images/GENESYS-ICON.svg'
/>
"
/><img
src=
"
<c:url
value=
'
${
cdnServers
.
next
}
/html/1/images/GENESYS-LOGO.svg'
/>
"
/></a>
</div>
<ul
class=
"nav navbar-nav nav-menu-admin"
>
<li
class=
"hidden-sm"
>
<a
href=
"
<c:url
value=
'/welcome'
/>
"
title=
"
<spring:message
code=
'menu.home'
/>
"
>
<spring:message
code=
"menu.home"
/>
</a>
</li>
<li
class=
"dropdown"
id=
"user-management-menu-item"
>
<a
href=
"#"
class=
"dropdown-toggle"
data-toggle=
"dropdown"
role=
"button"
aria-haspopup=
"true"
aria-expanded=
"false"
>
Users
<span
class=
"caret"
></span>
</a>
<ul
class=
"dropdown-menu pull-left"
>
<li>
<a
href=
"
<c:url
value=
'/admin/users/'
/>
"
>
<spring:message
code=
"user.pulldown.users"
/></a>
</li>
<li>
<a
href=
"
<c:url
value=
'/admin/teams/'
/>
"
>
<spring:message
code=
"user.pulldown.teams"
/></a>
</li>
<li>
<a
href=
"
<c:url
value=
'/admin/oauth-clients/'
/>
"
class=
""
>
OAuth clients
</a>
</li>
</ul>
</li>
<li
class=
"dropdown"
id=
"repository-menu-item"
>
<a
href=
"#"
class=
"dropdown-toggle"
data-toggle=
"dropdown"
role=
"button"
aria-haspopup=
"true"
aria-expanded=
"false"
>
<spring:message
code=
"menu.admin.repository"
/>
<span
class=
"caret"
></span>
</a>
<ul
class=
"dropdown-menu pull-left"
>
<li>
<a
href=
"
<c:url
value=
'/admin/r/files/'
/>
"
>
<spring:message
code=
"menu.admin.repository.files"
/>
</a>
</li>
<li>
<a
href=
"
<c:url
value=
'/admin/r/g'
/>
"
>
<spring:message
code=
"menu.admin.repository.galleries"
/>
</a>
</li>
</ul>
</li>
<li
class=
"dropdown"
id=
"cluster-menu-item"
>
<a
href=
"#"
class=
"dropdown-toggle"
data-toggle=
"dropdown"
role=
"button"
aria-haspopup=
"true"
aria-expanded=
"false"
>
Cluster
<span
class=
"caret"
></span>
</a>
<ul
class=
"dropdown-menu pull-left"
>
<li
id=
"hazelcast-menu-item"
>
<a
class=
""
href=
"
<c:url
value=
'/admin/hazelcast/'
/>
"
>
<spring:message
code=
"menu.admin.hazelcast"
/></a>
</li>
<li
id=
"cache-menu-item"
>
<a
class=
""
href=
"
<c:url
value=
'/admin/cache/'
/>
"
>
<spring:message
code=
"menu.admin.caches"
/>
</a>
</li>
<li>
<a
href=
"
<c:url
value=
'/admin/elastic/'
/>
"
class=
""
>
Elasticsearch
</a>
</li>
</ul>
</li>
<li
class=
"dropdown"
id=
"cluster-menu-item"
>
<a
href=
"#"
class=
"dropdown-toggle"
data-toggle=
"dropdown"
role=
"button"
aria-haspopup=
"true"
aria-expanded=
"false"
>
Data
<span
class=
"caret"
></span>
</a>
<ul
class=
"dropdown-menu pull-left"
>
<li
id=
"ds2-menu-item"
>
<a
class=
""
href=
"
<c:url
value=
'/admin/ds2/'
/>
"
>
<spring:message
code=
"menu.admin.ds2"
/>
</a>
</li>
<li
id=
"kpi-menu-item"
>
<a
class=
""
href=
"
<c:url
value=
'/admin/kpi/'
/>
"
>
<spring:message
code=
"menu.admin.kpi"
/>
</a>
</li>
</ul>
</li>
<li
id=
"kpi-menu-item"
>
<a
class=
""
href=
"
<c:url
value=
'/admin/bsh'
/>
"
>
<spring:message
code=
"menu.admin.beanshell"
/>
</a>
</li>
<li
id=
"logger-menu-item"
>
<a
class=
""
href=
"
<c:url
value=
'/admin/logger/'
/>
"
>
<spring:message
code=
"menu.admin.loggers"
/>
</a>
</li>
</ul>
</div>
<body>
<%@ include
file=
"header.jsp"
%>
<div
class=
"col-md-5 col-lg-2 no-space"
>
<ul
class=
"nav navbar-nav navbar-right"
>
<%@ include
file=
"languages.jspf"
%>
</ul>
</div>
</div>
</div>
</nav>
</div>
<
div
class=
"adm
in
-
page
"
>
<
nav
class=
"navbar navbar-default navbar-inverse navbar-fixed-top
"
>
<
!-- Beg
in
page
content --
>
<
div
id=
"content"
class=
"
<sitemesh:write
property=
'body.class'
/>
"
>
<div
class=
"container-fluid"
>
<div
class=
"navbar-header"
>
<button
type=
"button"
class=
"humburger-btn navbar-toggle collapsed pull-left"
data-toggle=
"collapse"
data-target=
"#navbar"
aria-expanded=
"false"
aria-controls=
"navbar"
>
<span
class=
"sr-only"
>
Toggle navigation
</span>
<span
class=
"icon-bar"
></span>
<span
class=
"icon-bar"
></span>
<span
class=
"icon-bar"
></span>
</button>
<%--<a class="navbar-brand" href="<c:url value="/admin/" />"> <spring:message code="page.home.title" /> </a>--%>
<a
class=
"navbar-brand nav-logo clearfix"
href=
"
<c:url
value=
"/admin/"
/>
"
><img
src=
"
<c:url
value=
"
${
cdnServers
.
next
}
/html/1/images/GENESYS-ICON.svg"
/>
"
/><img
src=
"/html/1/images/GENESYS-LOGO.svg"
/></a>
<div
id=
"content-header"
class=
"row"
>
<sitemesh:write
property=
"page.header"
/>
</div>
<div
id=
"navbar"
class=
"collapse navbar-collapse"
>
<div
class=
"col-md-7 col-lg-10 no-space"
>
<div
class=
"navbar-header"
>
<button
type=
"button"
class=
"humburger-btn navbar-toggle collapsed pull-left"
data-toggle=
"collapse"
data-target=
"#navbar"
aria-expanded=
"false"
aria-controls=
"navbar"
>
<span
class=
"sr-only"
>
Toggle navigation
</span>
<span
class=
"icon-bar"
></span>
<span
class=
"icon-bar"
></span>
<span
class=
"icon-bar"
></span>
</button>
<%--<a class="navbar-brand" href="<c:url value="/admin/" />"> <spring:message code="page.home.title" /> </a>--%>
<a
class=
"navbar-brand nav-logo clearfix"
href=
"
<c:url
value=
"/admin/"
/>
"
><img
src=
"
<c:url
value=
"
${
cdnServers
.
next
}
/html/1/images/GENESYS-ICON.svg"
/>
"
/><img
src=
"
<c:url
value=
"
${
cdnServers
.
next
}
/html/1/images/GENESYS-LOGO.svg"
/>
"
/></a>
</div>
<ul
class=
"nav navbar-nav nav-menu-admin"
>
<li
class=
"hidden-sm"
>
<a
href=
"
<c:url
value=
"/welcome"
/>
"
title=
"
<spring:message
code=
"menu.home"
/>
"
>
<spring:message
code=
"menu.home"
/>
</a>
</li>
<li
id=
"cache-menu-item"
>
<a
class=
""
href=
"
<c:url
value=
"/admin/cache/"
/>
"
>
<spring:message
code=
"menu.admin.caches"
/>
</a>
</li>
<li>
<a
href=
"
<c:url
value=
"/admin/elastic/"
/>
"
class=
""
>
Elasticsearch
</a>
</li>
<li
class=
"dropdown"
id=
"user-management-menu-item"
>
<a
href=
"#"
class=
"dropdown-toggle"
data-toggle=
"dropdown"
role=
"button"
aria-haspopup=
"true"
aria-expanded=
"false"
>
<spring:message
code=
"menu.admin.usermanagement"
/>
<span
class=
"caret"
></span></a>
<ul
class=
"dropdown-menu pull-left"
>
<li>
<a
href=
"
<c:url
value=
"/admin/users/"
/>
"
>
<spring:message
code=
"user.pulldown.users"
/></a>
</li>
<li>
<a
href=
"
<c:url
value=
"/admin/teams/"
/>
"
>
<spring:message
code=
"user.pulldown.teams"
/></a>
</li>
<li>
<a
href=
"
<c:url
value=
"/admin/oauth-clients/"
/>
"
class=
""
>
OAuth clients
</a>
</li>
</ul>
</li>
<li
class=
"dropdown"
id=
"repository-menu-item"
>
<a
href=
"#"
class=
"dropdown-toggle"
data-toggle=
"dropdown"
role=
"button"
aria-haspopup=
"true"
aria-expanded=
"false"
>
<spring:message
code=
"menu.admin.repository"
/>
<span
class=
"caret"
></span>
</a>
<ul
class=
"dropdown-menu pull-left"
>
<li>
<a
href=
"
<c:url
value=
"/admin/r/files/"
/>
"
>
<spring:message
code=
"menu.admin.repository.files"
/>
</a>