Skip to content

Commit

Permalink
[MNG-8257] Model Dialect
Browse files Browse the repository at this point in the history
Introduce symmetric counterpart to ModelParser.

---

https://issues.apache.org/jira/browse/MNG-8257
  • Loading branch information
cstamas committed Sep 25, 2024
1 parent 2c6846b commit 4eaa9c5
Show file tree
Hide file tree
Showing 12 changed files with 551 additions and 0 deletions.
46 changes: 46 additions & 0 deletions api/maven-api-core/src/main/java/org/apache/maven/api/Dialect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Immutable;

import static org.apache.maven.api.ExtensibleEnums.dialect;

/**
* Dialect.
* <p>
* This extensible enum has one defined value, {@link #XML},
* but can be extended by registering a {@code org.apache.maven.api.spi.DialectProvider}.
* <p>
* Implementation must have {@code equals()} and {@code hashCode()} implemented, so implementations of this interface
* can be used as keys.
*
* @since 4.0.0
*/
@Experimental
@Immutable
@SuppressWarnings("checkstyle:InterfaceIsType")
public interface Dialect extends ExtensibleEnum {

/**
* The "xml" dialect, the essence of Maven.
*/
Dialect XML = dialect("xml");
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@

abstract class ExtensibleEnums {

static Dialect dialect(String id) {
return new DefaultDialect(id);
}

static Language language(String id) {
return new DefaultLanguage(id);
}
Expand Down Expand Up @@ -88,6 +92,13 @@ public Set<DependencyScope> dependencyScopes() {
}
}

private static class DefaultDialect extends DefaultExtensibleEnum implements Dialect {

DefaultDialect(String id) {
super(id);
}
}

private static class DefaultProjectScope extends DefaultExtensibleEnum implements ProjectScope {

DefaultProjectScope(String id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.services;

import org.apache.maven.api.Dialect;

public interface DialectRegistry extends ExtensibleEnumRegistry<Dialect> {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.services;

import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import org.apache.maven.api.Dialect;
import org.apache.maven.api.Service;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.api.model.Model;

/**
* Dialect manager, that offers passage between various dialects.
*/
public interface ModelDialectManager extends Service {
/**
* Returns the available dialects, never {@code null}. Result set has at least one element, the {@link org.apache.maven.api.Dialect#XML}
* which is present in core.
*/
@Nonnull
Set<Dialect> getAvailableDialects();

/**
* Reads the model from given directory in given dialect.
*
* @param dir the directory from where to read, never {@code null}
* @param dialect the dialect to use to read, never {@code null}
* @param options the options for reading
* @return optional with the model that was read or empty
* @throws IllegalArgumentException if unknown dialect was asked for
*/
@Nonnull
Optional<Model> readModel(@Nonnull Path dir, @Nonnull Dialect dialect, @Nullable Map<String, ?> options);

/**
* Write the model to given directory in given dialect.
*
* @param dir the directory to where to write, never {@code null}
* @param dialect the dialect to use to write, never {@code null}
* @param model the model to write, never {@code null}
* @param options the options for writing
* @return optional with file path where write happened or empty
* @throws IllegalArgumentException if unknown dialect was asked for
*/
@Nonnull
Optional<Path> writeModel(
@Nonnull Path dir, @Nonnull Dialect dialect, @Nonnull Model model, @Nullable Map<String, ?> options);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.spi;

import org.apache.maven.api.Dialect;
import org.apache.maven.api.annotations.Consumer;
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.di.Named;

/**
* @since 4.0.0
*/
@Experimental
@Consumer
@Named
public interface DialectProvider extends ExtensibleEnumProvider<Dialect> {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.spi;

import org.apache.maven.api.Dialect;
import org.apache.maven.api.annotations.Consumer;
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.di.Named;

/**
* @since 4.0.0
*/
@Experimental
@Consumer
@Named
public interface ModelDialectProvider {
/**
* The {@link Dialect} this provider handles.
*/
@Nonnull
Dialect getDialect();

/**
* The dialect specific parser.
*/
@Nonnull
ModelParser getModelParser();

/**
* The dialect specific writer.
*/
@Nonnull
ModelWriter getModelWriter();
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@
/**
* The {@code ModelParser} interface is used to locate and read {@link Model}s from the file system.
* This allows plugging in additional syntaxes for the main model read by Maven when building a project.
* <p>
* Note: to provide Maven model "dialect", that can have models translated from-to, implement {@link ModelDialectProvider}
* that compose pairs of parser and writer (make dialect symmetrical).
*
* @since 4.0.0
* @see ModelDialectProvider
* @see DialectProvider
*/
@Experimental
@Consumer
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.spi;

import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;

import org.apache.maven.api.annotations.Consumer;
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.api.di.Named;
import org.apache.maven.api.model.Model;

/**
* The {@code ModelWriter} interface is used to write {@link Model}s to the file system.
* This allows plugging in additional syntaxes for the main model write.
* <p>
* Note: to provide Maven model "dialect", that can have models translated from-to, implement {@link ModelDialectProvider}
* that compose pairs of parser and writer (make dialect symmetrical).
*
* @since 4.0.0
* @see ModelDialectProvider
* @see DialectProvider
*/
@Experimental
@Consumer
@Named
public interface ModelWriter extends SpiService {

/**
* Targets the pom in the given directory.
*
* @param dir the directory to target the pom for, never {@code null}
* @return a {@code Path} pointing to the targeted pom file, or an empty {@code Optional} if serializer refuses to target.
*/
@Nonnull
Optional<Path> target(@Nonnull Path dir);

/**
* Write out given model into given directory. The actual file (within directory) is decided by implementation,
* and is returned upon successful write operation.
*
* @param target the file where to write out model, never {@code null}.
* @param model the model to write out. never {@code null}
* @param options possible writing options, may be {@code null}
* @throws ModelWriterException if the model could not be written
*/
@Nonnull
void write(@Nonnull Path target, @Nonnull Model model, @Nullable Map<String, ?> options)
throws ModelWriterException;

/**
* Target and write out the model in the specified directory.
* This is equivalent to {@code target(dir).map(s -> write(s, model, options))}.
*
* @param dir the directory to target the pom for, never {@code null}
* @param model the model to write out, never {@code null}.
* @param options possible parsing options, may be {@code null}
* @return an optional with pom file path
* @throws ModelWriterException if the target model cannot be written
*/
@Nonnull
default Optional<Path> targetAndWrite(@Nonnull Path dir, @Nonnull Model model, @Nullable Map<String, ?> options)
throws ModelWriterException {
return target(dir).map(s -> {
write(s, model, options);
return s;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.spi;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.services.MavenException;

@Experimental
public class ModelWriterException extends MavenException {
public ModelWriterException() {
this(null, null);
}

public ModelWriterException(String message) {
this(message, null);
}

public ModelWriterException(String message, Throwable cause) {
super(message, cause);
}
}
Loading

0 comments on commit 4eaa9c5

Please sign in to comment.