|
40 | 40 |
|
41 | 41 | package org.glassfish.jersey.examples.oauth2.googleclient.resource; |
42 | 42 |
|
| 43 | +import java.net.URI; |
43 | 44 | import java.util.ArrayList; |
44 | 45 | import java.util.List; |
| 46 | +import java.util.logging.Logger; |
45 | 47 |
|
46 | 48 | import javax.ws.rs.GET; |
47 | 49 | import javax.ws.rs.Path; |
48 | 50 | import javax.ws.rs.Produces; |
49 | 51 | import javax.ws.rs.client.Client; |
50 | 52 | import javax.ws.rs.client.WebTarget; |
51 | 53 | import javax.ws.rs.core.Context; |
52 | | -import javax.ws.rs.core.MediaType; |
53 | 54 | import javax.ws.rs.core.Response; |
54 | 55 | import javax.ws.rs.core.UriBuilder; |
55 | 56 | import javax.ws.rs.core.UriInfo; |
56 | 57 |
|
| 58 | +import javax.servlet.ServletContext; |
| 59 | + |
57 | 60 | import org.glassfish.jersey.client.oauth2.OAuth2ClientSupport; |
58 | 61 | import org.glassfish.jersey.client.oauth2.OAuth2CodeGrantFlow; |
59 | 62 | import org.glassfish.jersey.client.oauth2.OAuth2FlowGoogleBuilder; |
|
64 | 67 | import org.glassfish.jersey.examples.oauth2.googleclient.model.AllTaskListsModel; |
65 | 68 | import org.glassfish.jersey.examples.oauth2.googleclient.model.TaskListModel; |
66 | 69 | import org.glassfish.jersey.examples.oauth2.googleclient.model.TaskModel; |
| 70 | +import org.glassfish.jersey.filter.LoggingFilter; |
67 | 71 | import org.glassfish.jersey.jackson.JacksonFeature; |
68 | 72 | import org.glassfish.jersey.server.mvc.Template; |
69 | 73 |
|
|
74 | 78 | */ |
75 | 79 | @Path("tasks") |
76 | 80 | public class TaskResource { |
| 81 | + |
77 | 82 | private static final String GOOGLE_TASKS_BASE_URI = "https://www.googleapis.com/tasks/v1/"; |
| 83 | + |
78 | 84 | @Context |
79 | 85 | private UriInfo uriInfo; |
| 86 | + @Context |
| 87 | + private ServletContext servletContext; |
80 | 88 |
|
81 | 89 | @GET |
82 | 90 | @Template(name = "/tasks.mustache") |
83 | 91 | @Produces("text/html") |
84 | 92 | public Response getTasks() { |
| 93 | + // check oauth setup |
| 94 | + if (SimpleOAuthService.getClientIdentifier() == null) { |
| 95 | + final URI uri = UriBuilder.fromUri(servletContext.getContextPath()) |
| 96 | + .path("/index.html") //to show "Enter your Client Id and Secret" setup page |
| 97 | + .build(); |
| 98 | + return Response.seeOther(uri).build(); |
| 99 | + } |
| 100 | + // check access token |
85 | 101 | if (SimpleOAuthService.getAccessToken() == null) { |
86 | | - final String redirectURI = UriBuilder.fromUri(uriInfo.getBaseUri()) |
87 | | - .path("oauth2/authorize").build().toString(); |
88 | | - |
89 | | - final OAuth2CodeGrantFlow flow = OAuth2ClientSupport.googleFlowBuilder( |
90 | | - SimpleOAuthService.getClientIdentifier(), |
91 | | - redirectURI, |
92 | | - "https://www.googleapis.com/auth/tasks.readonly") |
93 | | - .prompt(OAuth2FlowGoogleBuilder.Prompt.CONSENT).build(); |
94 | | - |
95 | | - SimpleOAuthService.setFlow(flow); |
96 | | - |
97 | | - // start the flow |
98 | | - final String googleAuthURI = flow.start(); |
99 | | - |
100 | | - // redirect user to Google Authorization URI. |
101 | | - return Response.seeOther(UriBuilder.fromUri(googleAuthURI).build()).build(); |
| 102 | + return googleAuthRedirect(); |
102 | 103 | } |
103 | 104 | // We have already an access token. Query the data from Google API. |
104 | 105 | final Client client = SimpleOAuthService.getFlow().getAuthorizedClient(); |
105 | | - final AllTaskListsModel allTaskListsModel = getTasks(client); |
106 | | - return Response.ok(allTaskListsModel).type(MediaType.TEXT_HTML_TYPE).build(); |
| 106 | + return getTasksResponse(client); |
107 | 107 | } |
108 | 108 |
|
| 109 | + /** |
| 110 | + * Prepare redirect response to Google Tasks API auth consent request. |
| 111 | + * |
| 112 | + * @return redirect response to Google Tasks API auth consent request |
| 113 | + */ |
| 114 | + private Response googleAuthRedirect() { |
| 115 | + final String redirectURI = UriBuilder.fromUri(uriInfo.getBaseUri()) |
| 116 | + .path("oauth2/authorize").build().toString(); |
| 117 | + |
| 118 | + final OAuth2CodeGrantFlow flow = OAuth2ClientSupport.googleFlowBuilder( |
| 119 | + SimpleOAuthService.getClientIdentifier(), |
| 120 | + redirectURI, |
| 121 | + "https://www.googleapis.com/auth/tasks.readonly") |
| 122 | + .prompt(OAuth2FlowGoogleBuilder.Prompt.CONSENT).build(); |
| 123 | + |
| 124 | + SimpleOAuthService.setFlow(flow); |
| 125 | + |
| 126 | + // start the flow |
| 127 | + final String googleAuthURI = flow.start(); |
| 128 | + |
| 129 | + // redirect user to Google Authorization URI. |
| 130 | + return Response.seeOther(UriBuilder.fromUri(googleAuthURI).build()).build(); |
| 131 | + } |
109 | 132 |
|
110 | 133 | /** |
111 | 134 | * Queries task data from google. |
| 135 | + * |
112 | 136 | * @param client Client configured for authentication with access token. |
113 | | - * @return String html Google task data. |
| 137 | + * @return Google task data response or redirect to google authorize page response. |
114 | 138 | */ |
115 | | - private static AllTaskListsModel getTasks(final Client client) { |
| 139 | + private Response getTasksResponse(final Client client) { |
116 | 140 | client.register(JacksonFeature.class); |
| 141 | + client.register(new LoggingFilter(Logger.getLogger("example.client.tasks"), true)); |
| 142 | + |
117 | 143 | final WebTarget baseTarget = client.target(GOOGLE_TASKS_BASE_URI); |
118 | 144 | final Response response = baseTarget.path("users/@me/lists").request().get(); |
119 | 145 |
|
120 | | - final TaskRootBean taskRootBean = response.readEntity(TaskRootBean.class); |
| 146 | + final List<TaskListModel> listOfTaskLists; |
| 147 | + switch (response.getStatus()) { |
| 148 | + case 401: //Response.Status.UNAUTHORIZED |
| 149 | + SimpleOAuthService.setAccessToken(null); |
| 150 | + return googleAuthRedirect(); |
| 151 | + case 200: //Response.Status.OK |
| 152 | + listOfTaskLists = processTaskLists(baseTarget, response.readEntity(TaskRootBean.class)); |
| 153 | + break; |
| 154 | + default: |
| 155 | + listOfTaskLists = null; |
| 156 | + } |
| 157 | + |
| 158 | + final AllTaskListsModel tasks = new AllTaskListsModel(listOfTaskLists); |
| 159 | + return Response.ok(tasks).build(); |
| 160 | + } |
121 | 161 |
|
122 | | - final List<TaskListModel> listOfTaskLists = new ArrayList<TaskListModel>(); |
| 162 | + /** |
| 163 | + * Process users task lists and read task details. Collect just |
| 164 | + * @param baseTarget base JAX-RS client target with oauth context configured |
| 165 | + * @param taskRootBean root task bean to be processed |
| 166 | + * @return Detailed list of non-completed tasks or {@code null} if there is no task list available. |
| 167 | + */ |
| 168 | + private List<TaskListModel> processTaskLists(final WebTarget baseTarget, final TaskRootBean taskRootBean) { |
| 169 | + final List<TaskListModel> listOfTaskLists = new ArrayList<>(); |
123 | 170 | for (final TaskListBean taskListBean : taskRootBean.getItems()) { |
124 | | - final List<TaskModel> taskList = new ArrayList<TaskModel>(); |
| 171 | + final List<TaskModel> taskList = new ArrayList<>(); |
125 | 172 | final WebTarget listTarget = baseTarget.path("lists/{tasklist}/tasks") |
126 | 173 | .resolveTemplate("tasklist", taskListBean.getId()); |
127 | 174 |
|
128 | 175 | final TaskListBean fullTaskListBean = listTarget.request().get(TaskListBean.class); |
129 | 176 | for (final TaskBean taskBean : fullTaskListBean.getTasks()) { |
130 | | - taskList.add(new TaskModel(taskBean.getTitle())); |
| 177 | + if (taskBean.getCompleted() == null) { |
| 178 | + taskList.add(new TaskModel(taskBean.getTitle())); |
| 179 | + } |
131 | 180 | } |
132 | | - final TaskListModel listModel = new TaskListModel(taskListBean == null ? "No tasks were found. Define some tasks." |
133 | | - : taskListBean.getTitle(), taskList); |
134 | | - listOfTaskLists.add(listModel); |
135 | | - |
| 181 | + listOfTaskLists.add(new TaskListModel(taskListBean.getTitle(), taskList.size() > 0 ? taskList : null)); |
136 | 182 | } |
137 | | - return new AllTaskListsModel(listOfTaskLists); |
| 183 | + return listOfTaskLists.size() > 0 ? listOfTaskLists : null; |
138 | 184 | } |
| 185 | + |
139 | 186 | } |
0 commit comments