![JAR search and dependency download from the Maven repository](/logo.png)
objectos.way.Web Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of objectos.way Show documentation
Show all versions of objectos.way Show documentation
Objectos Way allows you to build web applications using only Java.
/*
* Copyright (C) 2023-2024 Objectos Software LTDA.
*
* 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 objectos.way;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.time.Clock;
import java.time.Duration;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.function.Consumer;
/**
* The Objectos Web main class.
*/
public final class Web {
public sealed interface Form permits WebForm {
public sealed interface Config permits WebFormConfig {
void spec(Relation value);
void action(String value);
}
public sealed interface Field {
String id();
String name();
String label();
}
public sealed interface TextInput extends Field permits WebFormTextInput {
String type();
}
static Form create(Consumer config) {
WebFormConfig builder;
builder = new WebFormConfig();
config.accept(builder);
return builder.build();
}
boolean isValid();
String action();
List fields();
}
/**
* The parsed and decoded body of a {@code application/x-www-form-urlencoded}
* HTTP message.
*/
public sealed interface FormData permits WebFormData {
/**
* Parse the body of the specified HTTP request as if it is the body of a
* {@code application/x-www-form-urlencoded} HTTP message.
*
* @param http
* the HTTP exchange to parse
*
* @throws UncheckedIOException
* if an I/O error occurs while reading the body
*/
static FormData parse(Http.Exchange http) throws UncheckedIOException, Http.UnsupportedMediaTypeException {
return WebFormData.parse(http);
}
/**
* Parse the specified request body as if it is the body of a
* {@code application/x-www-form-urlencoded} HTTP message.
*
* @param body
* the request body to parse
*
* @throws UncheckedIOException
* if an I/O error occurs while reading the body
*/
static FormData parseRequestBody(Http.RequestBody body) throws UncheckedIOException {
return WebFormData.parse(body);
}
/**
* Returns the names of all of the fields contained in this form data
*
* @return the names of all of the fields contained in this form data
*/
Set names();
/**
* Returns the first decoded value associated to the specified field name or
* {@code null} if the field is not present.
*
* @param name
* the field name
*
* @return the first decoded value or {@code null}
*/
String get(String name);
/**
* Returns a list containing all of the decoded values associated to the
* specified field name. This method returns an empty list if the field name
* is not present. In other words, this method never returns {@code null}.
*
* @param name
* the field name
*
* @return the first decoded value or {@code null}
*/
List getAll(String name);
/**
* Returns the first decoded value associated to the specified key or
* the specified {@code defaultValue} if the key is not present.
*
* @param key
* the key to search for
* @param defaultValue
* the value to return if the key is not present
*
* @return the first decoded value or the {@code defaultValue}
*/
String getOrDefault(String key, String defaultValue);
/**
* Returns the number of distinct keys
*
* @return the number of distinct keys
*/
int size();
}
/**
* An abstract HTTP module suited for web applications.
*/
public static abstract class Module extends WebModule {
/**
* Sole constructor.
*/
protected Module() {}
}
/**
* Allows for pagination of data tables in an web application.
*/
public sealed interface Paginator extends Sql.PageProvider permits WebPaginator {
/**
* Configures the creation of a {@code Paginator} instance.
*/
sealed interface Config permits WebPaginatorConfig {
/**
* Sets the page size to the specified value.
*
* @param value
* the page size
*
* @throws IllegalArgumentException
* if the value is equal to or lesser than {@code 0}
*/
void pageSize(int value);
/**
* Sets the query parameter name to be used in the pagination.
*
* @param value
* the parameter name
*
* @throws IllegalArgumentException
* if {@code value} is empty or blank
*/
void parameterName(String value);
/**
* Sets the request target for pagination.
*
* @param value
* the {@code Http.RequestTarget} instance
*/
void requestTarget(Http.RequestTarget value);
/**
* Sets the total number of rows to be paginated.
*
* @param value
* the total row count
*
* @throws IllegalArgumentException
* if {@code value} is less than {@code 0}
*/
void rowCount(int value);
}
/**
* Creates a new paginator instance with the specified configuration.
*
* @param config
* the paginator configuration
*
* @return a new paginator instance
*/
static Paginator create(Consumer config) {
WebPaginatorConfig builder;
builder = new WebPaginatorConfig();
config.accept(builder);
return builder.build();
}
/**
* Returns the current page.
*
* @return the current page
*/
@Override
Sql.Page page();
/**
* Returns the index (1-based) of the first row in the current page.
*
* @return the index (1-based) of the first row in the current page.
*/
int firstRow();
/**
* Returns the index (1-based) of the last row in the current page.
*
* @return the index (1-based) of the last row in the current page.
*/
int lastRow();
/**
* Returns the total number of rows.
*
* @return the total number of rows.
*/
int rowCount();
boolean hasNext();
boolean hasPrevious();
String nextHref();
String previousHref();
}
public sealed interface Relation permits WebRelation {
public sealed interface Config permits WebRelationConfig {
void name(String value);
void stringAttribute(Consumer config);
}
public sealed interface Attribute {
public sealed interface Config {
void name(String value);
void description(String value);
void required();
}
String name();
String description();
boolean required();
}
public sealed interface StringAttribute extends Attribute permits WebRelationStringAttribute {
public sealed interface Config extends Attribute.Config permits WebRelationStringAttributeConfig {
void maxLength(int value);
void pattern(String value, String message);
}
}
static Relation create(Consumer config) {
WebRelationConfig builder;
builder = new WebRelationConfig();
config.accept(builder);
return builder.build();
}
String name();
List attributes();
}
/**
* An HTTP handler for serving the static files of an web application.
*/
public sealed interface Resources extends AutoCloseable, Http.Handler permits WebResources {
/**
* Configures the creation of an Web Resources instance.
*/
public sealed interface Config permits WebResourcesConfig {
/**
* Map file extension names to content type (media type) values as defined
* by the specified properties string.
*
*
* A typical usage is:
*
*
* config.contentTypes("""
* .css: text/stylesheet; charset=utf-8
* .js: text/javascript; charset=utf-8
* .jpg: image/jpeg
* .woff: font/woff2
* """);
*
*
* Which causes:
*
*
* - files ending in {@code .css} to be served with
* {@code Content-Type: text/stylesheet; charset=utf-8};
* - files ending in {@code .js} to be served with
* {@code Content-Type: text/javascript; charset=utf-8};
* - files ending in {@code .jpg} to be served with
* {@code Content-Type: image/jpeg};
* - files ending in {@code .woff} to be served with
* {@code Content-Type: font/woff2};
*
*
* @param propertiesString
* a string with a file extension / content-type mapping in each
* line
*
* @return this object
*/
Config contentTypes(String propertiesString);
/**
* Set the note sink to the specified instance.
*
* @param noteSink
* the note sink instance
*
* @return this object
*/
Config noteSink(Note.Sink noteSink);
/**
* Serve the contents of the specified directory as if they were at the
* root of the web server.
*
* @param directory
* the directory whose contents are to be served
*
* @return this object
*/
Config serveDirectory(Path directory);
/**
* Serve at the specified path name a file with the specified
* contents. The behavior of this option is not specified if the
* contents of the array is changed while this option is configuring the
* creation of a resources instance.
*
*
* A typical usage is:
*
*
* config.serveFile("/robots.txt", Files.readAllBytes(robotsPath));
*
* @param pathName
* the path of the resource to be served. It must start with a '/'
* character.
*
* @param contents
* the contents of the resource to be served.
*
* @return this object
*/
Config serveFile(String pathName, byte[] contents);
/**
* Set the root directory of the web resources to the specified path.
*
* @param value
* the path of the directory
*
* @return this object
*/
Config rootDirectory(Path value);
}
/**
* Creates a new {@code Resources} instance with the specified
* configuration.
*
* @param config
* the configuration
*
* @return a newly created {@code Resources} instance with the specified
* configuration
*
* @throws IOException
* if an I/O error occurs
*/
static Resources create(ThrowingConsumer config) throws IOException {
WebResourcesConfig builder;
builder = new WebResourcesConfig();
config.accept(builder);
return builder.build();
}
/**
* Deletes the file at the specified path if it exists.
*
* @throws IOException
* if an I/O error occurs
*/
boolean deleteIfExists(String path) throws IOException;
/**
* Creates a new file at the specified path with the specified text content.
*
* @throws IOException
* if an I/O error occurs
*/
void writeMediaObject(String path, Lang.MediaObject contents) throws IOException;
/**
* Creates a new file at the specified path with the specified text content.
*
* @throws IOException
* if an I/O error occurs
*/
void writeString(String path, CharSequence contents, Charset charset) throws IOException;
}
/**
* An web session uniquely identifies the user of an application.
*/
public sealed interface Session permits WebSession {
/**
* Creates a new web session with the specified identifier.
*
* @param id
* the session identifier
*
* @return a newly created session object
*/
static Session create(String id) {
return new WebSession(id);
}
/**
* The identifier of this session.
*
* @return the identifier of this session.
*/
String id();
/**
* Returns the object associated to the specified class instance, or
* {@code null} if there's no object associated.
*
* @param the type of the object
*
* @param type
* the class instance to search for
*
* @return the object associated or {@code null} if there's no object
* associated
*/
T get(Class type);
/**
* Returns the object associated to the specified name, or {@code null} if
* there's no object associated.
*
* @param name
* the name to search for
*
* @return the object associated or {@code null} if there's no object
* associated
*/
Object get(String name);
Object put(Class type, T value);
Object put(String name, Object value);
Object remove(String name);
void invalidate();
}
/**
* Creates, stores and manages session instances.
*/
public sealed interface Store permits WebStore {
/**
* Configures the creation of a {@code Store} instance.
*/
public sealed interface Config permits WebStoreConfig {
/**
* Use the specified {@code clock} when setting session instances time
* related values.
*
* @param value
* the clock instance to use
*
* @return this object
*/
Config clock(Clock value);
/**
* Use the specified {@code name} when setting the client session cookie.
*
* @param name
* the cookie name to use
*
* @return this object
*/
Config cookieName(String name);
/**
* Sets the session cookie Path attribute to the specified value.
*
* @param path
* the value of the Path attribute
*
* @return this object
*/
Config cookiePath(String path);
/**
* Sets the session cookie Max-Age attribute to the specified value.
*
* @param duration
* the value of the Max-Age attribute
*
* @return this object
*/
Config cookieMaxAge(Duration duration);
/**
* Discards empty sessions, during a {@link Store#cleanUp()}
* operation, whose last access time is greater than the specified
* duration.
*
* @param duration
* the duration value
*
* @return this object
*/
Config emptyMaxAge(Duration duration);
/**
* Use the specified {@link Random} instance for generating session IDs.
*
* @param random
* the {@link Random} instance to use
*
* @return this object
*/
Config random(Random random);
}
/**
* Creates a new session store with the specified configuration.
*
* @param config
* the session store configuration
*
* @return a newly created session store with the specified
* configuration
*/
static Store create(Consumer config) {
WebStoreConfig builder;
builder = new WebStoreConfig();
config.accept(builder);
return builder.build();
}
void cleanUp();
/**
* Creates and immediately stores a new session instance.
*
* @return a newly created session instance.
*/
Session createNext();
void filter(Http.Exchange http);
/**
* Returns the session with the specified session ID; or returns
* {@code null} if the session does not exist.
*
* @param id
* the session ID
*
* @return the session with the specified session ID or {@code null}
*/
Session get(String id);
/**
* Returns a Set-Cookie header value for the specified session ID.
*
* @param id
* the session ID
*
* @return the value of a Set-Cookie header for the specified session ID
*/
String setCookie(String id);
/**
* Stores the specified {@code session} in this repository. If a session
* instance with the same ID is already managed by this repository then the
* existing session is replaced by the specified one.
*
* @param session
* the session instance to be stored
*
* @return the previously stored session instance or {@code null}
*/
Session store(Session session);
}
@FunctionalInterface
public interface ThrowingConsumer {
void accept(T config) throws E;
}
private Web() {}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy