Skip to content

Commit

Permalink
Support for jakarta servlet API
Browse files Browse the repository at this point in the history
This is a straight port from the guice-servlet code to support the new
jakarta servlet API classes (jakarta.*).
  • Loading branch information
hgschmie committed May 17, 2022
1 parent 4a84687 commit cb245d7
Show file tree
Hide file tree
Showing 72 changed files with 9,959 additions and 0 deletions.
5 changes: 5 additions & 0 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
<artifactId>guice-grapher</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-jakarta-servlet</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-jmx</artifactId>
Expand Down
2 changes: 2 additions & 0 deletions extensions/jakarta-servlet/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module=com.google.inject.servlet.jee
fragment=true
49 changes: 49 additions & 0 deletions extensions/jakarta-servlet/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.google.inject.extensions</groupId>
<artifactId>extensions-parent</artifactId>
<version>5.1.1-SNAPSHOT</version>
</parent>

<artifactId>guice-jakarta-servlet</artifactId>

<name>Google Guice - Extensions - JEE Servlet</name>

<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Automatic-Module-Name>com.google.guice.extensions.jee.servlet</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2022 Google Inc.
*
* 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 com.google.inject.servlet.jee;

import java.util.Map;

/**
* Abstract implementation for all servlet module bindings
*
* @author [email protected] (Sam Berlin)
*/
class AbstractServletModuleBinding<T> implements ServletModuleBinding {

private final Map<String, String> initParams;
private final T target;
private final UriPatternMatcher patternMatcher;

AbstractServletModuleBinding(
Map<String, String> initParams, T target, UriPatternMatcher patternMatcher) {
this.initParams = initParams;
this.target = target;
this.patternMatcher = patternMatcher;
}

@Override
public Map<String, String> getInitParams() {
return initParams;
}

@Override
public String getPattern() {
return patternMatcher.getOriginalPattern();
}

protected T getTarget() {
return target;
}

@Override
public UriPatternType getUriPatternType() {
return patternMatcher.getPatternType();
}

@Override
public boolean matchesUri(String uri) {
return patternMatcher.matches(uri);
}
}
64 changes: 64 additions & 0 deletions extensions/jakarta-servlet/src/com/google/inject/servlet/jee/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2022 Google Inc. All rights reserved.
# Author: [email protected] (Sam Berlin)
load("@rules_java//java:defs.bzl", "java_library")
load("//:mvn.bzl", "gen_maven_artifact")
load(
"//:build_defs.bzl",
"JAVAC_OPTS",
"POM_VERSION",
)

package(
default_visibility = ["//:src"],
)

java_library(
name = "request-scoped-annotation",
srcs = ["RequestScoped.java"],
javacopts = JAVAC_OPTS,
plugins = [
],
deps = [
"//third_party/java/jsr330_inject",
],
)

java_library(
name = "servlet",
srcs = glob(
["*.java"],
exclude = ["RequestScoped.java"],
),
javacopts = JAVAC_OPTS,
plugins = [
],
tags = ["maven_coordinates=com.google.inject.extensions:guice-servlet:" + POM_VERSION],
exports = [":request-scoped-annotation"],
deps = [
":request-scoped-annotation",
"//core/src/com/google/inject",
"//third_party/java/guava/base",
"//third_party/java/guava/collect",
"//third_party/java/guava/escape",
"//third_party/java/guava/net",
"//third_party/java/jsr330_inject",
"//third_party/java/servlet/servlet_api",
],
)

filegroup(
name = "javadoc-srcs",
srcs = glob(["*.java"]),
)

gen_maven_artifact(
name = "artifact",
artifact_id = "guice-servlet",
artifact_name = "Google Guice - Extensions - Servlet",
artifact_target = ":servlet",
artifact_target_libs = [
":request-scoped-annotation",
],
is_extension = True,
javadoc_srcs = [":javadoc-srcs"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* Copyright (C) 2022 Google Inc.
*
* 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 com.google.inject.servlet.jee;

import com.google.common.collect.Maps;
import com.google.inject.OutOfScopeException;
import java.io.IOException;
import java.util.Map;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpSession;

/**
* A wrapper for requests that makes requests immutable, taking a snapshot of the original request.
*
* @author [email protected] (Dhanji R. Prasanna)
*/
class ContinuingHttpServletRequest extends HttpServletRequestWrapper {

// We clear out the attributes as they are mutable and not thread-safe.
private final Map<String, Object> attributes = Maps.newHashMap();
private final Cookie[] cookies;

public ContinuingHttpServletRequest(HttpServletRequest request) {
super(request);

Cookie[] originalCookies = request.getCookies();
if (originalCookies != null) {
int numberOfCookies = originalCookies.length;
cookies = new Cookie[numberOfCookies];
for (int i = 0; i < numberOfCookies; i++) {
Cookie originalCookie = originalCookies[i];

// Snapshot each cookie + freeze.
// No snapshot is required if this is a snapshot of a snapshot(!)
if (originalCookie instanceof ImmutableCookie) {
cookies[i] = originalCookie;
} else {
cookies[i] = new ImmutableCookie(originalCookie);
}
}
} else {
cookies = null;
}
}

@Override
public HttpSession getSession() {
throw new OutOfScopeException("Cannot access the session in a continued request");
}

@Override
public HttpSession getSession(boolean create) {
throw new UnsupportedOperationException("Cannot access the session in a continued request");
}

@Override
public ServletInputStream getInputStream() throws IOException {
throw new UnsupportedOperationException("Cannot access raw request on a continued request");
}

@Override
public void setAttribute(String name, Object o) {
attributes.put(name, o);
}

@Override
public void removeAttribute(String name) {
attributes.remove(name);
}

@Override
public Object getAttribute(String name) {
return attributes.get(name);
}

@Override
public Cookie[] getCookies() {
// NOTE(user): Cookies themselves are mutable. However a ContinuingHttpServletRequest
// snapshots the original set of cookies it received and imprisons them in immutable
// form. Unfortunately, the cookie array itself is mutable and there is no way for us
// to avoid this. At worst, however, mutation effects are restricted within the scope
// of a single request. Continued requests are not affected after snapshot time.
return cookies;
}

private static final class ImmutableCookie extends Cookie {
public ImmutableCookie(Cookie original) {
super(original.getName(), original.getValue());

super.setMaxAge(original.getMaxAge());
super.setPath(original.getPath());
super.setComment(original.getComment());
super.setSecure(original.getSecure());
super.setValue(original.getValue());
super.setVersion(original.getVersion());

if (original.getDomain() != null) {
super.setDomain(original.getDomain());
}
}

@Override
public void setComment(String purpose) {
throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
}

@Override
public void setDomain(String pattern) {
throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
}

@Override
public void setMaxAge(int expiry) {
throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
}

@Override
public void setPath(String uri) {
throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
}

@Override
public void setSecure(boolean flag) {
throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
}

@Override
public void setValue(String newValue) {
throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
}

@Override
public void setVersion(int v) {
throw new UnsupportedOperationException("Cannot modify cookies on a continued request");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2022 Google Inc.
*
* 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 com.google.inject.servlet.jee;

import java.io.IOException;
import jakarta.inject.Inject;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;

/**
* This default pipeline simply dispatches to web.xml's servlet pipeline.
*
* @author [email protected] (Dhanji R. Prasanna)
* @see ManagedFilterPipeline See Also ManagedFilterPipeline.
*/
class DefaultFilterPipeline implements FilterPipeline {
@Inject
DefaultFilterPipeline() {}

@Override
public void initPipeline(ServletContext context) {}

@Override
public void destroyPipeline() {}

@Override
public void dispatch(
ServletRequest request, ServletResponse response, FilterChain proceedingFilterChain)
throws IOException, ServletException {

proceedingFilterChain.doFilter(request, response);
}
}
Loading

0 comments on commit cb245d7

Please sign in to comment.