Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,47 @@ The project was relocated from <https://github.com/sonatype/sisu-build-api>. Als

## Provided APIs

### Messages API

The Messages API provides a modern, flexible way to create and manage build messages/markers that inform users in an IDE about issues in their files. It uses a builder pattern for constructing messages in a more convenient and extensible way compared to the legacy BuildContext message methods.

**Key Features:**
- Builder pattern for flexible message construction
- Clear separation of concerns from resource operations
- Support for error, warning, and info messages
- File path-based message management
- Optional line and column information
- Optional exception cause association

**Example Usage:**

```java
@Inject
private Messages messages;

public void execute() {
// Create an error message
messages.buildError(Paths.get("/path/to/file.java"))
.line(42)
.column(10)
.message("Syntax error")
.cause(exception)
.create();

// Create a warning message
messages.buildWarning(Paths.get("/path/to/file.java"))
.line(15)
.message("Deprecated method used")
.create();

// Clear messages for a specific file
messages.clear(Paths.get("/path/to/file.java"));

// Clear all messages
messages.clearAll();
}
```

### Progress

The API allows a mojo to report progress in a way that is suitable to be shown as a progressbar as well as check if the user wants the mojo to gracefully abort its current operation.
Expand Down
176 changes: 176 additions & 0 deletions src/main/java/org/codehaus/plexus/build/messages/DefaultMessages.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
Copyright (c) 2008 Sonatype, Inc. All rights reserved.

This program is licensed to you under the Apache License Version 2.0,
and you may not use this file except in compliance with the Apache License Version 2.0.
You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.

Unless required by applicable law or agreed to in writing,
software distributed under the Apache License Version 2.0 is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
*/
package org.codehaus.plexus.build.messages;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import java.nio.file.Path;

import org.codehaus.plexus.build.BuildContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Default implementation of the Messages interface.
* <p>
* This implementation delegates to the BuildContext for compatibility with existing
* message handling infrastructure. It logs messages and calls the legacy BuildContext
* message API.
* </p>
*/
@Named("default")
@Singleton
public class DefaultMessages implements Messages {

private static final Logger logger = LoggerFactory.getLogger(DefaultMessages.class);

private final BuildContext buildContext;

/**
* Creates a new DefaultMessages instance.
*
* @param buildContext the BuildContext to which messages will be delegated
*/
@Inject
public DefaultMessages(BuildContext buildContext) {
this.buildContext = buildContext;
}

@Override
public void clearAll() {
// This is a no-op in the default implementation
// Custom implementations may provide actual clearing functionality
}

@Override
public void clear(Path path) {
if (path != null) {
buildContext.removeMessages(path.toFile());
}
}

@Override
public MessageBuilder buildError(Path path) {
return build(MessageType.ERROR, path);
}

@Override
public MessageBuilder buildWarning(Path path) {
return build(MessageType.WARNING, path);
}

@Override
public MessageBuilder buildInfo(Path path) {
return build(MessageType.INFO, path);
}

@Override
public MessageBuilder build(MessageType type, Path path) {
return new MessageBuilder(type, path, this::handleMessage);
}

/**
* Handles a message by logging it and delegating to the BuildContext.
*
* @param message the message to handle
*/
private void handleMessage(Message message) {
// Log the message
String logMessage = formatLogMessage(message);

switch (message.getType()) {
case ERROR:
logger.error(logMessage, message.getCause());
break;
case WARNING:
logger.warn(logMessage, message.getCause());
break;
case INFO:
logger.info(logMessage, message.getCause());
break;
}

// Delegate to BuildContext for compatibility
if (message.getPath() != null) {
int severity = mapTypeToSeverity(message.getType());
buildContext.addMessage(
message.getPath().toFile(),
message.getLine(),
message.getColumn(),
message.getMessage(),
severity,
message.getCause());
}
}

/**
* Formats a message for logging.
*
* @param message the message to format
* @return the formatted log message
*/
private String formatLogMessage(Message message) {
StringBuilder sb = new StringBuilder();

if (message.getPath() != null) {
sb.append(message.getPath().toAbsolutePath());
}

if (message.getLine() > 0 && message.getColumn() > 0) {
sb.append(" [");
sb.append(message.getLine());
sb.append(':').append(message.getColumn());
sb.append("]");
} else if (message.getLine() > 0) {
sb.append(" [");
sb.append(message.getLine());
sb.append("]");
} else if (message.getColumn() > 0) {
sb.append(" [:");
sb.append(message.getColumn());
sb.append("]");
}

if (message.getMessage() != null) {
if (sb.length() > 0) {
sb.append(": ");
}
sb.append(message.getMessage());
}

return sb.toString();
}

/**
* Maps a MessageType to a BuildContext severity level.
*
* @param type the message type
* @return the corresponding BuildContext severity
*/
private int mapTypeToSeverity(MessageType type) {
switch (type) {
case ERROR:
return BuildContext.SEVERITY_ERROR;
case WARNING:
return BuildContext.SEVERITY_WARNING;
case INFO:
default:
// There's no INFO severity in BuildContext (only WARNING and ERROR),
// so we map INFO messages to WARNING to ensure they are still visible in the IDE.
// Custom implementations may provide different mappings.
return BuildContext.SEVERITY_WARNING;
}
}
}
89 changes: 89 additions & 0 deletions src/main/java/org/codehaus/plexus/build/messages/Message.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
Copyright (c) 2008 Sonatype, Inc. All rights reserved.
This program is licensed to you under the Apache License Version 2.0,
and you may not use this file except in compliance with the Apache License Version 2.0.
You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing,
software distributed under the Apache License Version 2.0 is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
*/
package org.codehaus.plexus.build.messages;

import java.nio.file.Path;

/**
* Represents a message with all its parameters.
* This class holds the collected parameters for a message that can be created through the MessageBuilder.
*/
public class Message {
private final MessageType type;
private final Path path;
private final int line;
private final int column;
private final String message;
private final Throwable cause;

/**
* Creates a new message with the specified parameters.
*
* @param type the message type
* @param path the file path associated with this message
* @param line the line number (1-based, 0 for unknown)
* @param column the column number (1-based, 0 for unknown)
* @param message the message text
* @param cause the exception cause, can be null
*/
public Message(MessageType type, Path path, int line, int column, String message, Throwable cause) {
this.type = type;
this.path = path;
this.line = line;
this.column = column;
this.message = message;
this.cause = cause;
}

/**
* @return the message type
*/
public MessageType getType() {
return type;
}

/**
* @return the file path
*/
public Path getPath() {
return path;
}

/**
* @return the line number (1-based, 0 for unknown)
*/
public int getLine() {
return line;
}

/**
* @return the column number (1-based, 0 for unknown)
*/
public int getColumn() {
return column;
}

/**
* @return the message text
*/
public String getMessage() {
return message;
}

/**
* @return the exception cause, or null if none
*/
public Throwable getCause() {
return cause;
}
}
Loading