├── plugin
├── src
│ └── main
│ │ ├── resources
│ │ └── index.jelly
│ │ ├── webapp
│ │ ├── activiti-logo.xcf
│ │ └── images
│ │ │ ├── 24x24
│ │ │ └── activiti.png
│ │ │ └── 48x48
│ │ │ └── activiti.png
│ │ └── java
│ │ └── org
│ │ └── jenkinsci
│ │ └── plugins
│ │ └── activiti_explorer
│ │ ├── XmlPatcher.java
│ │ └── ActivitiExplorer.java
└── pom.xml
├── dto
├── src
│ └── main
│ │ └── java
│ │ └── org
│ │ └── jenkinsci
│ │ └── plugins
│ │ └── activiti_explorer
│ │ └── dto
│ │ └── UserDTO.java
└── pom.xml
├── activiti-explorer-override
├── src
│ └── main
│ │ └── java
│ │ └── org
│ │ └── jenkinsci
│ │ └── plugins
│ │ └── jenkow
│ │ └── activiti
│ │ └── override
│ │ ├── JenkinsMainMenuBar.java
│ │ ├── JenkinsManagementMenuBar.java
│ │ ├── ExplorerApp2.java
│ │ ├── JenkinsProcessEngineFactory.java
│ │ ├── JenkinsComponentFactories.java
│ │ ├── ServletContextDataSource.java
│ │ ├── JenkinsUser.java
│ │ └── JenkinsLoginHandler.java
└── pom.xml
└── pom.xml
/plugin/src/main/resources/index.jelly:
--------------------------------------------------------------------------------
1 |
2 | Embeds Activiti Explorer inside Jenkins
3 |
4 |
--------------------------------------------------------------------------------
/plugin/src/main/webapp/activiti-logo.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkinsci/activiti-explorer-plugin/master/plugin/src/main/webapp/activiti-logo.xcf
--------------------------------------------------------------------------------
/plugin/src/main/webapp/images/24x24/activiti.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkinsci/activiti-explorer-plugin/master/plugin/src/main/webapp/images/24x24/activiti.png
--------------------------------------------------------------------------------
/plugin/src/main/webapp/images/48x48/activiti.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jenkinsci/activiti-explorer-plugin/master/plugin/src/main/webapp/images/48x48/activiti.png
--------------------------------------------------------------------------------
/dto/src/main/java/org/jenkinsci/plugins/activiti_explorer/dto/UserDTO.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.activiti_explorer.dto;
2 |
3 | /**
4 | * @author Kohsuke Kawaguchi
5 | */
6 | public class UserDTO {
7 | public String id, firstName, lastName, fullName, email;
8 |
9 | public boolean isAdmin, isUser;
10 | }
11 |
--------------------------------------------------------------------------------
/activiti-explorer-override/src/main/java/org/jenkinsci/plugins/jenkow/activiti/override/JenkinsMainMenuBar.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.jenkow.activiti.override;
2 |
3 | import org.activiti.explorer.ui.alfresco.AlfrescoMainMenuBar;
4 | import org.activiti.explorer.ui.mainlayout.MainMenuBar;
5 |
6 | /**
7 | * Customize the main menu bar to get rid of the profile link
8 | *
9 | * @author Kohsuke Kawaguchi
10 | * @see AlfrescoMainMenuBar
11 | */
12 | public class JenkinsMainMenuBar extends MainMenuBar {
13 | @Override
14 | protected boolean useProfile() {
15 | // profile is not editable
16 | return false;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/activiti-explorer-override/src/main/java/org/jenkinsci/plugins/jenkow/activiti/override/JenkinsManagementMenuBar.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.jenkow.activiti.override;
2 |
3 | import org.activiti.explorer.ui.alfresco.AlfrescoManagementMenuBar;
4 | import org.activiti.explorer.ui.management.ManagementMenuBar;
5 |
6 | /**
7 | * Get rid of the users and groups UI because we won't let those things edited in Activiti
8 | *
9 | * @author Kohsuke Kawaguchi
10 | * @see AlfrescoManagementMenuBar
11 | */
12 | public class JenkinsManagementMenuBar extends ManagementMenuBar {
13 | protected void addUsersToolbarEntry() {
14 | }
15 |
16 | protected void addGroupToolbarEntry() {
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/dto/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.jenkins-ci.plugins
7 | activiti-explorer-plugin-parent
8 | 1.0-SNAPSHOT
9 |
10 |
11 | activiti-explorer-dto
12 | Serializable objects that are passed between AE and Jenkins to carry information back and forth
13 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/activiti-explorer-override/src/main/java/org/jenkinsci/plugins/jenkow/activiti/override/ExplorerApp2.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.jenkow.activiti.override;
2 |
3 | import org.activiti.explorer.ExplorerApp;
4 |
5 | import javax.servlet.http.HttpServletRequest;
6 | import javax.servlet.http.HttpServletResponse;
7 |
8 | /**
9 | * @author Kohsuke Kawaguchi
10 | */
11 | public class ExplorerApp2 extends ExplorerApp {
12 | @Override
13 | public void onRequestStart(HttpServletRequest request, HttpServletResponse response) {
14 | // AE caches the logged in user into a session, which means it won't notice when the user logs out in Jenkins
15 | // or logs in. Our JenkinsLoginHandler is efficient, no need to cache this.
16 | setUser(null);
17 |
18 | super.onRequestStart(request, response);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/activiti-explorer-override/src/main/java/org/jenkinsci/plugins/jenkow/activiti/override/JenkinsProcessEngineFactory.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.jenkow.activiti.override;
2 |
3 | import org.activiti.engine.ProcessEngine;
4 | import org.springframework.beans.factory.FactoryBean;
5 | import org.springframework.web.context.ServletContextAware;
6 |
7 | import javax.servlet.ServletContext;
8 |
9 | /**
10 | * @author Kohsuke Kawaguchi
11 | */
12 | public class JenkinsProcessEngineFactory implements FactoryBean, ServletContextAware {
13 | private ServletContext servletContext;
14 |
15 | @Override
16 | public ProcessEngine getObject() throws Exception {
17 | return (ProcessEngine)servletContext.getAttribute(ProcessEngine.class.getName());
18 | }
19 |
20 | @Override
21 | public Class getObjectType() {
22 | return ProcessEngine.class;
23 | }
24 |
25 | @Override
26 | public boolean isSingleton() {
27 | return true;
28 | }
29 |
30 | @Override
31 | public void setServletContext(ServletContext servletContext) {
32 | this.servletContext = servletContext;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/activiti-explorer-override/src/main/java/org/jenkinsci/plugins/jenkow/activiti/override/JenkinsComponentFactories.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.jenkow.activiti.override;
2 |
3 | import org.activiti.explorer.ComponentFactories;
4 | import org.activiti.explorer.Environments;
5 | import org.activiti.explorer.ui.custom.ToolBar;
6 | import org.activiti.explorer.ui.mainlayout.MainMenuBarFactory;
7 | import org.activiti.explorer.ui.management.ManagementMenuBarFactory;
8 |
9 | /**
10 | * More hook for injecting custom UI components.
11 | *
12 | * @author Kohsuke Kawaguchi
13 | */
14 | public class JenkinsComponentFactories extends ComponentFactories {
15 | public JenkinsComponentFactories() {
16 | // TODO: send patch to Activiti to clean up this hack
17 | factories.put(MainMenuBarFactory.class, new MainMenuBarFactory(){
18 | @Override
19 | protected Class getDefaultComponentClass() {
20 | return JenkinsMainMenuBar.class;
21 | }
22 | });
23 | factories.put(ManagementMenuBarFactory.class, new ManagementMenuBarFactory() {
24 | @Override
25 | protected Class extends ToolBar> getDefaultComponentClass() {
26 | return JenkinsManagementMenuBar.class;
27 | }
28 | });
29 | setEnvironment(Environments.ACTIVITI);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/activiti-explorer-override/src/main/java/org/jenkinsci/plugins/jenkow/activiti/override/ServletContextDataSource.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.jenkow.activiti.override;
2 |
3 | import org.springframework.beans.factory.FactoryBean;
4 | import org.springframework.web.context.ServletContextAware;
5 |
6 | import javax.servlet.ServletContext;
7 | import javax.sql.DataSource;
8 |
9 | /**
10 | * Returns {@link DataSource} injected through {@link ServletContext} attribute.
11 | *
12 | * This is how the jenkow plugin passes in the {@link DataSource} to the embedded activiti explorer.
13 | *
14 | * @author Kohsuke Kawaguchi
15 | */
16 | public class ServletContextDataSource implements FactoryBean, ServletContextAware {
17 | private ServletContext servletContext;
18 |
19 | @Override
20 | public void setServletContext(ServletContext servletContext) {
21 | this.servletContext = servletContext;
22 | }
23 |
24 | @Override
25 | public Object getObject() throws Exception {
26 | Object o = servletContext.getAttribute(ServletContextDataSource.class.getName());
27 | if (o==null)
28 | throw new IllegalStateException("ServletContext doesn't contain a DataSource");
29 | return o;
30 | }
31 |
32 | @Override
33 | public Class> getObjectType() {
34 | return DataSource.class;
35 | }
36 |
37 | @Override
38 | public boolean isSingleton() {
39 | return true;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/activiti-explorer-override/src/main/java/org/jenkinsci/plugins/jenkow/activiti/override/JenkinsUser.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.jenkow.activiti.override;
2 |
3 | import org.activiti.explorer.identity.LoggedInUser;
4 | import org.jenkinsci.plugins.activiti_explorer.dto.UserDTO;
5 |
6 | /**
7 | * @author Kohsuke Kawaguchi
8 | */
9 | public class JenkinsUser implements LoggedInUser {
10 | private final UserDTO dto;
11 |
12 | public JenkinsUser(UserDTO dto) {
13 | if (dto ==null)
14 | throw new IllegalArgumentException("No information given");
15 | this.dto = dto;
16 | }
17 |
18 | public String getId() {
19 | return dto.id;
20 | }
21 |
22 | public String getFirstName() {
23 | return dto.firstName;
24 | }
25 |
26 | public String getLastName() {
27 | return dto.lastName;
28 | }
29 |
30 | public String getFullName() {
31 | return dto.fullName;
32 | }
33 |
34 | public String getPassword() {
35 | return null;
36 | }
37 |
38 | public boolean isAdmin() {
39 | return dto.isAdmin;
40 | }
41 |
42 | public boolean isUser() {
43 | return dto.isUser;
44 | }
45 |
46 | @Override
47 | public int hashCode() {
48 | return getId().hashCode();
49 | }
50 |
51 | @Override
52 | public boolean equals(Object obj) {
53 | if (obj instanceof LoggedInUser)
54 | return ((LoggedInUser)obj).getId().equals(getId());
55 | return false;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/activiti-explorer-override/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.jenkins-ci.plugins
7 | activiti-explorer-plugin-parent
8 | 1.0-SNAPSHOT
9 |
10 |
11 | activiti-explorer-override
12 | Additional code to be injected into Activiti Explorer to tweak its behaviour
13 |
14 |
15 |
16 | org.springframework
17 | spring-beans
18 | 3.1.2.RELEASE
19 | provided
20 |
21 |
22 | org.activiti
23 | activiti-engine
24 | ${activiti.version}
25 | provided
26 |
27 |
28 | ${project.groupId}
29 | activiti-explorer-dto
30 | ${project.version}
31 |
32 |
33 | org.activiti
34 | activiti-webapp-explorer2
35 | jar
36 | ${activiti.version}
37 | provided
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/plugin/src/main/java/org/jenkinsci/plugins/activiti_explorer/XmlPatcher.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.activiti_explorer;
2 |
3 | import org.dom4j.Document;
4 | import org.dom4j.DocumentException;
5 | import org.dom4j.Element;
6 | import org.dom4j.io.OutputFormat;
7 | import org.dom4j.io.SAXReader;
8 | import org.dom4j.io.XMLWriter;
9 |
10 | import java.io.File;
11 | import java.io.FileOutputStream;
12 | import java.io.IOException;
13 |
14 | /**
15 | * @author Kohsuke Kawaguchi
16 | */
17 | abstract class XmlPatcher {
18 | private final File xml;
19 | protected Document dom;
20 |
21 | public XmlPatcher(File xml) throws IOException, DocumentException {
22 | this.xml = xml;
23 | run();
24 | }
25 |
26 | protected Element findBean(String id) {
27 | Element bean = (Element)dom.selectSingleNode(String.format("/*/*[@id='%s' or @name='%s']", id,id));
28 | if (bean==null)
29 | throw new IllegalStateException("Can't find the "+id+" bean in "+xml);
30 | return bean;
31 | }
32 |
33 | protected void overrideBeanTo(String id, String className) {
34 | Element pe = findBean(id);
35 | pe.elements().clear();
36 | pe.attributes().clear();
37 | pe.addAttribute("id", id);
38 | pe.addAttribute("class", className);
39 | }
40 |
41 | protected void swapClass(String id, String className) {
42 | Element pe = findBean(id);
43 | pe.addAttribute("class", className);
44 | }
45 |
46 | protected void removeBean(String id) {
47 | findBean(id).detach();
48 | }
49 |
50 | public abstract void patch();
51 |
52 | public void run() throws DocumentException, IOException {
53 | dom = new SAXReader().read(xml);
54 |
55 | patch();
56 |
57 | FileOutputStream out = new FileOutputStream(xml);
58 | try {
59 | new XMLWriter(out, OutputFormat.createPrettyPrint()).write(dom);
60 | } finally {
61 | out.close();
62 | }
63 |
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.jenkins-ci.plugins
7 | plugin
8 | 1.455
9 |
10 |
11 |
12 | activiti-explorer-plugin-parent
13 | 1.0-SNAPSHOT
14 | pom
15 | https://wiki.jenkins-ci.org/display/JENKINS/Activiti+Explorer+Plugin
16 |
17 |
18 | plugin
19 | dto
20 | activiti-explorer-override
21 |
22 |
23 |
24 | 5.11
25 |
26 |
27 |
28 |
29 | The MIT License (MIT)
30 | http://www.opensource.org/licenses/mit-license.php
31 | repo
32 |
33 |
34 |
35 |
36 | scm:git:ssh://github.com/jenkinsci/activiti-explorer-plugin.git
37 | scm:git:ssh://git@github.com/jenkinsci/activiti-explorer-plugin.git
38 | https://github.com/jenkinsci/activiti-explorer-plugin
39 |
40 |
41 |
42 |
43 | repo.jenkins-ci.org
44 | http://repo.jenkins-ci.org/public/
45 |
46 |
47 | repo.activiti
48 | https://maven.alfresco.com/nexus/content/groups/public/
49 |
50 |
51 |
52 |
53 | repo.jenkins-ci.org
54 | http://repo.jenkins-ci.org/public/
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/activiti-explorer-override/src/main/java/org/jenkinsci/plugins/jenkow/activiti/override/JenkinsLoginHandler.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.jenkow.activiti.override;
2 |
3 | import org.activiti.explorer.ui.login.LoginHandler;
4 | import org.activiti.explorer.identity.LoggedInUser;
5 | import org.jenkinsci.plugins.activiti_explorer.dto.UserDTO;
6 |
7 | import javax.servlet.http.HttpServletRequest;
8 | import javax.servlet.http.HttpServletResponse;
9 | import java.util.Map;
10 |
11 | /**
12 | * @author Kohsuke Kawaguchi
13 | */
14 | public class JenkinsLoginHandler implements LoginHandler {
15 | /**
16 | * Authenticate the user with the given username and given password.
17 | *
18 | * @return the logged in user. Return null of authentication failed.
19 | */
20 | public LoggedInUser authenticate(String userName, String password) {
21 | throw new UnsupportedOperationException();
22 | }
23 |
24 | /**
25 | * Authenticate the current user. Use this to eg. shared autentication,
26 | * which can be done without the user actually having to provide
27 | * credentials.
28 | *
29 | * @return The logged in user. Return null, if no user can be logged in
30 | * automatically. When null is returned, user will be requested to provide
31 | * credentials.
32 | */
33 | public LoggedInUser authenticate(HttpServletRequest request, HttpServletResponse response) {
34 | return new JenkinsUser((UserDTO)request.getSession().getAttribute("jenkins.user"));
35 | }
36 |
37 | /**
38 | * Called when the user is logged out, should clear all context related
39 | * to authorization and authentication for the current logged in user.
40 | */
41 | public void logout(LoggedInUser userTologout) {
42 |
43 | }
44 |
45 | /**
46 | * Called when request started. Allows eg. validating of authentication or
47 | * renewing.
48 | */
49 | public void onRequestStart(HttpServletRequest request, HttpServletResponse response) {}
50 |
51 | /**
52 | * Called when request started. Allows eg. validating of authentication or
53 | * renewing.
54 | */
55 | public void onRequestEnd(HttpServletRequest request, HttpServletResponse response) {}
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/plugin/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 |
4 | org.jenkins-ci.plugins
5 | activiti-explorer-plugin-parent
6 | 1.0-SNAPSHOT
7 |
8 |
9 | activiti-explorer
10 | hpi
11 |
12 |
13 |
14 | ${project.groupId}
15 | activiti-explorer-dto
16 | ${project.version}
17 |
18 |
19 | com.cisco.step.jenkins.plugins
20 | jenkow-plugin
21 | 0.2.6-SNAPSHOT
22 |
23 |
24 | com.cloudbees
25 | vietnam4j-core
26 | 1.7
27 |
28 |
29 | ${project.groupId}
30 | activiti-explorer-override
31 | 1.0-SNAPSHOT
32 |
33 |
34 | org.jenkins-ci.modules
35 | sshd
36 | 1.1
37 | provided
38 |
39 |
40 |
41 |
42 |
43 |
44 | org.jenkins-ci.tools
45 | maven-hpi-plugin
46 | 1.93
47 |
48 |
49 | org.apache.maven.plugins
50 | maven-dependency-plugin
51 | 2.5.1
52 |
53 |
54 | copy
55 | generate-resources
56 |
57 | copy
58 |
59 |
60 |
61 |
62 | org.activiti
63 | activiti-webapp-explorer2
64 | war
65 | ${activiti.version}
66 | ${project.build.directory}/classes
67 | activiti-explorer.war
68 |
69 |
70 | ${project.groupId}
71 | activiti-explorer-override
72 | jar
73 | ${project.version}
74 | ${project.build.directory}/classes
75 | activiti-explorer-override.jar
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | repo.jenkins-ci.org
89 | http://repo.jenkins-ci.org/public/
90 |
91 |
92 | repo.activiti
93 | https://maven.alfresco.com/nexus/content/groups/public/
94 |
95 |
96 |
97 |
98 |
99 | repo.jenkins-ci.org
100 | http://repo.jenkins-ci.org/public/
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/plugin/src/main/java/org/jenkinsci/plugins/activiti_explorer/ActivitiExplorer.java:
--------------------------------------------------------------------------------
1 | package org.jenkinsci.plugins.activiti_explorer;
2 |
3 | import com.cisco.step.jenkins.plugins.jenkow.JenkowBuilder.DescriptorImpl;
4 | import com.cisco.step.jenkins.plugins.jenkow.JenkowEngine;
5 | import com.cloudbees.vietnam4j.ProxiedWebApplication;
6 | import hudson.Extension;
7 | import hudson.Util;
8 | import hudson.model.UnprotectedRootAction;
9 | import hudson.model.User;
10 | import jenkins.model.Jenkins;
11 | import org.acegisecurity.Authentication;
12 | import org.activiti.engine.ProcessEngine;
13 | import org.apache.commons.io.IOUtils;
14 | import org.dom4j.DocumentException;
15 | import org.jenkinsci.plugins.activiti_explorer.dto.UserDTO;
16 | import org.jenkinsci.plugins.jenkow.activiti.override.JenkinsProcessEngineFactory;
17 | import org.jenkinsci.plugins.jenkow.activiti.override.ServletContextDataSource;
18 | import org.kohsuke.stapler.StaplerRequest;
19 | import org.kohsuke.stapler.StaplerResponse;
20 |
21 | import javax.inject.Inject;
22 | import javax.servlet.ServletException;
23 | import javax.servlet.http.HttpServletRequest;
24 | import javax.servlet.http.HttpSession;
25 | import java.io.File;
26 | import java.io.FileOutputStream;
27 | import java.io.IOException;
28 | import java.net.URL;
29 | import java.net.URLClassLoader;
30 | import java.util.jar.JarEntry;
31 | import java.util.jar.JarInputStream;
32 |
33 | /**
34 | * Activiti Explorer web application embedded inside Jenkins.
35 | *
36 | * @author Kohsuke Kawaguchi
37 | */
38 | @Extension
39 | public class ActivitiExplorer implements UnprotectedRootAction {
40 | private ProxiedWebApplication webApp;
41 |
42 | @Inject
43 | DescriptorImpl descriptor;
44 |
45 | public String getIconFileName() {
46 | return "/plugin/activiti-explorer/images/24x24/activiti.png";
47 | }
48 |
49 | public String getDisplayName() {
50 | return "Activiti Explorer";
51 | }
52 |
53 | public String getUrlName() {
54 | return "activiti-explorer";
55 | }
56 |
57 | public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException {
58 | ProxiedWebApplication webApp = getProxyWebApplication(req);
59 |
60 | HttpSession session = req.getSession();
61 | HttpSession ps = webApp.getProxiedSession(session);
62 | UserDTO oldUser = (UserDTO)ps.getAttribute("jenkins.user");
63 | UserDTO newUser = createUserInfo();
64 | if (!mapToId(oldUser).equals(mapToId(newUser))) {
65 | // force a new session. AE isn't designed to anticipate the user change without invalidating a session,
66 | // but Jenkins does that. So when we see that the user has changed in Jenkins, force a new session
67 | // (but only in AE.)
68 | webApp.clearProxiedSession(session);
69 | ps = webApp.getProxiedSession(session);
70 | }
71 |
72 | ps.setAttribute("jenkins.user", newUser);
73 |
74 |
75 | webApp.handleRequest(req, rsp);
76 | }
77 |
78 | private String mapToId(UserDTO o) {
79 | return o==null ? "\u0000" : o.id;
80 | }
81 |
82 | /**
83 | * Creates {@link UserDTO} that represents the currently logged-in user.
84 | */
85 | private UserDTO createUserInfo() {
86 | Authentication a = Jenkins.getAuthentication();
87 | User u = User.current();
88 |
89 | UserDTO user = new UserDTO();
90 | user.id = a.getName();
91 | user.firstName = u != null ? u.getFullName() : a.getName();
92 | user.lastName = "";
93 | user.fullName = u != null ? u.getFullName() : a.getName();
94 | user.isAdmin = Jenkins.getInstance().getACL().hasPermission(a,Jenkins.ADMINISTER);
95 | user.isUser = true;
96 |
97 | return user;
98 | }
99 |
100 | /**
101 | * Extracts a war file into the specified directory.
102 | */
103 | private void extract(URL war, File dir) throws IOException {
104 | if (dir.exists())
105 | Util.deleteRecursive(dir);
106 |
107 | JarInputStream jar = new JarInputStream(war.openStream());
108 | try {
109 | JarEntry e;
110 | while ((e=jar.getNextJarEntry())!=null) {
111 | File dst = new File(dir,e.getName());
112 | if (e.isDirectory())
113 | dst.mkdirs();
114 | else {
115 | dst.getParentFile().mkdirs();
116 | FileOutputStream out = new FileOutputStream(dst);
117 | try {
118 | IOUtils.copy(jar, out);
119 | } finally {
120 | out.close();
121 | }
122 |
123 | if (e.getTime()>=0)
124 | dst.setLastModified(e.getTime());
125 | }
126 | }
127 | } finally {
128 | jar.close();
129 | }
130 | }
131 |
132 | /**
133 | * Patch activiti-explorer war file so that we can inject our stuff into it.
134 | */
135 | private void patch(File war) throws DocumentException, IOException {
136 | new XmlPatcher(new File(war,"WEB-INF/activiti-standalone-context.xml")) {
137 | public void patch() {
138 | // patch data source in
139 | overrideBeanTo("dataSource", ServletContextDataSource.class.getName());
140 |
141 | // single sign-on
142 | // can't load the class yet, so string
143 | overrideBeanTo("activitiLoginHandler", "org.jenkinsci.plugins.jenkow.activiti.override.JenkinsLoginHandler");
144 |
145 | // inject our own fully configured ProcessEngine
146 | overrideBeanTo("processEngine", JenkinsProcessEngineFactory.class.getName());
147 |
148 | // no more demo data generation
149 | removeBean("demoDataGenerator");
150 | }
151 | };
152 | new XmlPatcher(new File(war,"WEB-INF/activiti-ui-context.xml")) {
153 | public void patch() {
154 | // tweak the navigation bar
155 | overrideBeanTo("componentFactories", "org.jenkinsci.plugins.jenkow.activiti.override.JenkinsComponentFactories");
156 |
157 | swapClass("explorerApp","org.jenkinsci.plugins.jenkow.activiti.override.ExplorerApp2");
158 | }
159 | };
160 | }
161 |
162 | private synchronized ProxiedWebApplication getProxyWebApplication(StaplerRequest req) throws ServletException {
163 | if (webApp==null) {
164 | try {
165 | final ClassLoader ourLoader = getClass().getClassLoader();
166 |
167 | File war = new File(Jenkins.getInstance().getRootDir(), "cache/activiti-explorer");
168 | extract(ourLoader.getResource("activiti-explorer.war"),war);
169 | patch(war);
170 | webApp = new ProxiedWebApplication(
171 | war,
172 | req.getContextPath()+'/'+getUrlName());
173 |
174 | webApp.setParentLoaderHasPriority(true);
175 |
176 | webApp.addClassPath(ourLoader.getResource("activiti-explorer-override.jar"));
177 | // inject DataSource
178 | webApp.getProxiedServletContext().setAttribute(ServletContextDataSource.class.getName(),
179 | descriptor.getDatabase().getDataSource());
180 | webApp.getProxiedServletContext().setAttribute(ProcessEngine.class.getName(),
181 | JenkowEngine.getEngine());
182 |
183 | // pass through to the servlet container so that Activiti won't get confused
184 | // by what Jenkins loads (e.g., log4j version inconsistency)
185 | // but we do expose DTO classes to share them between two apps.
186 | webApp.setParentClassLoader(new URLClassLoader(new URL[0],HttpServletRequest.class.getClassLoader()) {
187 | @Override
188 | protected Class> findClass(String name) throws ClassNotFoundException {
189 | if (name.startsWith("org.jenkinsci.plugins.activiti_explorer.dto.")
190 | || name.startsWith("org.activiti.engine.")) {
191 | return getClass().getClassLoader().loadClass(name);
192 | }
193 | throw new ClassNotFoundException(name);
194 | }
195 | });
196 |
197 | webApp.start();
198 | } catch (Exception e) {
199 | throw new ServletException(e);
200 | }
201 | }
202 | return webApp;
203 | }
204 | }
205 |
--------------------------------------------------------------------------------