Git Product home page Git Product logo

c10n's People

Contributors

kevinrobayna avatar lelmarir avatar rodionmoiseev avatar sakamotodesu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

c10n's Issues

Add support for unformatted messages/resources

Currently all messages specified in @En("message"), @En(intRes="path/to/resource.txt"), are post-filtered through MessageFormat. This may be undesired, for example, when dealing with external resources scripted in some wiki format, like Markdown, since it may use {} notation.

MessageFormat supports escaping of {} but it is not very intuitive and may get quite verbose.

A possible solution would be to add an additional parameter to the annotation, e.g. raw = true, that would skip the MessageFormat filter.

Simplify Enum support (beta idea)

Inspired by @lelmarir Automated Enum binding with Guice commit.

Motivation

Currently providing locale sensitive translations for Enums is relatively complex. In overview it requires 2 steps:

  1. Create a separate c10n-interface with translations
  2. Install an "enumMapping" filter for the Enum in question

The biggest problems with this approach are:

  • Enum mapping cannot be checked at compile time, and thus is a pretty fragile mechanism. This also kind of goes against the compile-time safety of C10N.
  • Additional interface needs to be maintained for mapping only, which is boilerplaty and some static code inspection tools may not like it.
  • Translations are currently fetched by the filter, which is executed every time a c10n interface method is invoked, meaning more overhead.
  • Each new enum mapping needs to be explicitly installed during C10N configuration time, making maintenance more difficult

A Better Approach

Being able to specify translations directly on the values of the Enum seems to do the job better:

enum Pet {
    @En("Cat")
    @Ru("Кот")
    CAT,

    @En("Dog")
    @Ru("Собака")
    DOG
}

Enum-type arguments can be retrieved and cached at c10n initialization time, in the same way other standard translations are fetched, instead of c10n interface method invocation time.

This approach would make Enum support more transparent, with no extra configuration, and with less overhead.

It would also work transparently with other c10n extensions, such as external/internal resource loading, Guice support and Logging tool.

invalid checksum of pom in repo

You converted line endings in commit Converted CRLF to LF in commit fc740ac

This changed the sha-1 and md5 checksum of the pom file in the repo. it can't be validated now. you should either generate new checksums or revert the pom to the old one.

Question of custom Annotations

Hi rodionmoiseev,

in the user guide you have this example:

Messages_en.properties

com.example.gui.window.title = Hello, {0}!
com.example.gui.window.buttons.ok = OK
com.example.gui.window.buttons.cancel = Cancel

Messages_ru.properties

com.example.gui.window.title = Привет, {0}!
com.example.gui.window.buttons.ok = Да
com.example.gui.window.buttons.cancel = Отмена

How can i do this to result to this:

@target(ElementType.METHOD)
@retention(RetentionPolicy.RUNTIME)
public @interface PropertyKey {
String key();
String defaultValue();
String value();
}

package com.example.gui;

public interface Window {
@en("Hello, {0}!")
@ru("Привет, {0}!")
@PropertyKey(key="com.example.gui.window.title", defaultValue="Hello, {0}!")
String title(String userName);

@en("OK")
@ru("Да")
@PropertyKey(key="com.example.gui.window.buttons.ok", defaultValue="OK")
String ok();

@en("Cancel")
@ru("")
@PropertyKey(key="com.example.gui.window.buttons.cancel", defaultValue="Cancel")
String cancel();
}

Window msg = C10N.get(Window.class);
//get message
String ok = msg.ok();
//get message with parameter
String title = msg.title("James");

Thanks in advance.

Cheers

astrapi69

Support for message bundles

Add official message bundle support.

Required features:

  • Binding one or more message bundles (with message look-up in bundle declaration order)
  • A fairly flexible bundle key declaration mechanism
    • Default key generation based on class FQDN and method name (plus arguments)
    • Explicit key declaration using an annotation
    • Key declaration scopes
      • Interface scope - all containing method keys are relative to interface's key
      • configuration scope - all method keys are relative to configuration scope key
      • a way to override relative scope and specify an absolute key.

Failed to import this project on IntelliJ14 .

I read wiki -> contribute and tried to import this project on IntelliJ14, but failed.

  • Mac 10.9.5

  • IntelliJ IDEA 14.1.5

  • idea.log error

    2015-11-11 18:48:26,201 [2105590]   WARN - nal.AbstractExternalSystemTask - No such property: sonatypeUsername for class: org.gradle.api.publication.maven.internal.ant.DefaultGroovyMavenDeployer
    com.intellij.openapi.externalSystem.model.LocationAwareExternalSystemException: No such property: sonatypeUsername for class: org.gradle.api.publication.maven.internal.ant.DefaultGroovyMavenDeployer
        at org.jetbrains.plugins.gradle.service.project.AbstractProjectImportErrorHandler.createUserFriendlyError(AbstractProjectImportErrorHandler.java:103)
        at org.jetbrains.plugins.gradle.service.project.BaseProjectImportErrorHandler.getUserFriendlyError(BaseProjectImportErrorHandler.java:158)
        at org.jetbrains.plugins.gradle.service.project.BaseGradleProjectResolverExtension.getUserFriendlyError(BaseGradleProjectResolverExtension.java:438)
        at org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension.getUserFriendlyError(AbstractProjectResolverExtension.java:164)
        at com.android.tools.idea.gradle.project.AndroidGradleProjectResolver.getUserFriendlyError(AndroidGradleProjectResolver.java:322)
        at org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension.getUserFriendlyError(AbstractProjectResolverExtension.java:164)
        at org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension.getUserFriendlyError(AbstractProjectResolverExtension.java:164)
        at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver$ProjectConnectionDataNodeFunction.fun(GradleProjectResolver.java:366)
        at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver$ProjectConnectionDataNodeFunction.fun(GradleProjectResolver.java:332)
        at org.jetbrains.plugins.gradle.service.project.GradleExecutionHelper.execute(GradleExecutionHelper.java:215)
        at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.resolveProjectInfo(GradleProjectResolver.java:97)
        at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.resolveProjectInfo(GradleProjectResolver.java:65)
        at com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolverImpl$1.produce(RemoteExternalSystemProjectResolverImpl.java:41)
        at com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolverImpl$1.produce(RemoteExternalSystemProjectResolverImpl.java:37)
        at com.intellij.openapi.externalSystem.service.remote.AbstractRemoteExternalSystemService.execute(AbstractRemoteExternalSystemService.java:59)
        at com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolverImpl.resolveProjectInfo(RemoteExternalSystemProjectResolverImpl.java:37)
        at com.intellij.openapi.externalSystem.service.remote.wrapper.ExternalSystemProjectResolverWrapper.resolveProjectInfo(ExternalSystemProjectResolverWrapper.java:49)
        at com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolveProjectTask.doExecute(ExternalSystemResolveProjectTask.java:51)
        at com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask.execute(AbstractExternalSystemTask.java:138)
        at com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask.execute(AbstractExternalSystemTask.java:124)
        at com.intellij.openapi.externalSystem.util.ExternalSystemUtil$4.execute(ExternalSystemUtil.java:540)
        at com.intellij.openapi.externalSystem.util.ExternalSystemUtil$5$1.run(ExternalSystemUtil.java:612)
        at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:563)
        at com.intellij.openapi.progress.impl.CoreProgressManager$8.run(CoreProgressManager.java:367)
        at com.intellij.openapi.progress.impl.CoreProgressManager$2.run(CoreProgressManager.java:152)
        at com.intellij.openapi.progress.impl.CoreProgressManager.a(CoreProgressManager.java:452)
        at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:402)
        at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:54)
        at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:137)
        at com.intellij.openapi.application.impl.ApplicationImpl$10$1.run(ApplicationImpl.java:617)
        at com.intellij.openapi.application.impl.ApplicationImpl$8.run(ApplicationImpl.java:400)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
        at java.lang.Thread.run(Thread.java:695)
        at org.jetbrains.ide.PooledThreadExecutor$1$1.run(PooledThreadExecutor.java:56)
    

Calling C10N.configure(...) multiple times

If C10N is used in a library, I think that the C10N.configure(...) function must be called from the lib itself. For example, the lib could use the default annotations.

Now, If C10N is used also in a project, which in turn is using the above mentioned library, another call to C10N.configure(...) can change the configuration. For example, custom annotations may be set.

I haven't made any test, but it seems to me that this could be an issue.
Am I missing anything?

Travis build fails due to Java incompatibility

Failure details: https://travis-ci.org/rodionmoiseev/c10n/builds/659192990

Installing oraclejdk8
$ export JAVA_HOME=~/oraclejdk8
$ export PATH="$JAVA_HOME/bin:$PATH"
$ ~/bin/install-jdk.sh --target "/home/travis/oraclejdk8" --workspace "/home/travis/.cache/install-jdk" --feature "8" --license "BCL"
Ignoring license option: BCL -- using GPLv2+CE by default
install-jdk.sh 2020-01-14
Expected feature release number in range of 9 to 15, but got: 8
The command "~/bin/install-jdk.sh --target "/home/travis/oraclejdk8" --workspace "/home/travis/.cache/install-jdk" --feature "8" --license "BCL"" failed and exited with 3 during .
Your build has been stopped.

Seems like Java 8 is no longer supported.

Support annotations directly on delegates

Consider the following use case:

interface Window{
  @En("Dialog title")
  Dialog dialog();
}

interface Dialog{
  @En("OK")
  String ok();
}

Currently, in order to get dialog title, one has to create an explicit Dialog.title() method, where as, it would be nice to be able to use the delegating method itself for holding the title. Thus, one would call System.out.println(window.dialog()) and that would print "Dialog title".

Question with messages

Hi there, i just saw your library and i had to try it because i think is a great idea use interface as elements to translate.

Trying a example code like:

import c10n.C10N;
import c10n.annotations.DefaultC10NAnnotations;
import c10n.annotations.En;
import c10n.annotations.Ru;

interface Message {
  @En ("Hi")
  @Ru ("Привет")
  String grettins ();
}
public class MainTest {
  private static final Message msg = C10N.get(Message.class);
  public static void main (String [] args) {
    C10N.configure(new DefaultC10NAnnotations());
    System.out.println(msg.grettins());
  }
}

This is my output

Message.grettins

But it should be Hi or Привет. You know which could be my problem?

In addition i would like to add spanish annotation language to c10n i just have to modify core/src/main/java/com/github/rodionmoiseev/c10n/annotations/ adding a class named es.java and DefaultC10NAnnotations adding

 bindAnnotation(En.class).toLocale(Locale.SPANISH);

Apostrophe character disappears

Consider a translation containing the apostrophe char ' like in the following example:

interface Messages {
    @It("L\'Italiano")
    String apostropheIssue();
}

Calling the apostropheIssue() method on the concrete class generated by C10N will result in the string LItaliano (i.e. the apostrophe is missing).

I've just created a JUnit test for this that I'm going to commit...

Configure file encoding of message bundles

As I understand it, UTF-8 is currently hard-coded when reading the message bundles. Our message bundles are ISO-8859-1 and it would be nice if we could configure that somehow.

What do you think?

Unable to build c10n: DefaultCodeGenerator.ResourceFile(File, String) undefined and DefaultCodeGenerator.ResourceFile.localeSuffix uninitialized

Eclipse IDE triggers a few warnings in

https://github.com/rodionmoiseev/c10n/blob/master/tools/src/main/java/c10n/tools/codegen/DefaultCodeGenerator.java
SHA: a210e88

  1. The constructor DefaultCodeGenerator.ResourceFile(File, String) is undefined at line 278
  2. The blank final field localeSuffix may not have been initialized at line 285
    private List<ResourceFile> findResourceFiles(File baseFile) {
        File parentDir = baseFile.getParentFile();
        String baseName = baseFile.getName();
        List<ResourceFile> res = new ArrayList<ResourceFile>();
        for (File f : parentDir.listFiles()) {
            int p = f.getName().lastIndexOf(".properties");
            if (f.getName().startsWith(baseName) && p > 0) {
                String localeSuffix = null;
                if (p > baseName.length() + 1) {
                    localeSuffix = f.getName().substring(baseName.length() + 1,
                            p);
                }
                res.add(new ResourceFile(f, localeSuffix));
            }
        }
        return res;
    }

    @Data
    private static final class ResourceFile {
        private final File file;
        private final String localeSuffix;
    }

Support specifying locale at c10n interface proxy creation time

Currenly one can explicitly change locale at configuration time, using C10NConfigBase#setLocale() or setLocaleProvider() methods. In order to dynamically change locale at runtime, one has to provide a custom locale provider, and make sure it provides the desired locale before invoking C10N.get(Class) method.

Even though this approach works, it is somewhat cumbersome. Also, in certain multi-user environments where user's locale cannot be statically determined from the current thread (e.g. Play 2 scala project) and has to be passed around with the request, simultaneously using multiple locales with one configuration is impossible.

Two possible solutions;

  1. Pass locale directly to C10N.get(Class) method, i.e. C10N.get(Class, Locale)
  2. Make it possible to create a light-weight clone of the current configuration with a different locale setting, i.e. implement a method C10NConfiguredModule.setLocale(Locale): C10NConfiguredModule that will create a new instance of the configured module, reusing all immutable internals, including string translations, but with the different locale setting.

Licensing is fishy

The copright in your library seems fishy:

Apache Cosmopolitan
Copyright 2012 The Apache Software Foundation

This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

C10n is not an apache foundation project so it should be something like:

Cosmopolitan
Copyright 2012 Moiseev Rodion
Licensed under the Apache License, Version 2.0

This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

Same with the files header, you used the one from the foundation itself, not the one described at the end of the license agreement:

Copyright [yyyy] [name of copyright owner]

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.
apache.org
Welcome to The Apache Software Foundation!
Home page of The Apache Software Foundation

Instantiate Guice bound instances on-demand

Hi,

First, let me say this is a really nice library - very easy to pick up and use :)

One thing I think could be improved though, is to provide an option of instantiating C10N interfaces on-demand when retrieved through Guice. At the moment, they're all created during injector initialisation so you can't, at runtime, change the locale of the instances provided through Guice.

Here's a rough idea of the change I'm proposing to the existing C10NModule (don't have git handy so not submitted as a patch, sorry)

protected void configure() {
    Set<Class<?>> c10nTypes = ... <snip>
    for (Class<?> c10nType : c10nTypes) {
        bind(c10nType).toProvider(new C10NProvider(c10nType));
    }
}

class C10NProvider<T> implements Provider<T> {
    private final Class<T> clazz;

    C10NProvider(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public T get() {
        return C10N.get(clazz);
    }
}

This way, we can change our locale at will, and it also means we can delay configuring C10N until right before we're ready to use it.

Update project to use Java 11

Currently the project is Java8 source/binary compatible, however Oracle will stop actively supporting Java8 from end of 2020.

Java11 is the next LTS version, and thus seems reasonable to be the candidate for the next official platform version for c10n.

The minimal fix would be to simply bump the source+binary compatibility requirements, make sure everything compiles and executes, and that Travis is happy.

Any source code fixes to use the latest Java11 syntax should have their own home as another issue. Cheers.

Move Guice extension source into its own top-level module

Currently Guice extension is located under the core module, in a separate source set. Source sets work well when all source sets use the same dependencies, however in case of guice-extension the additional Guice dependency makes the Gradle set-up more complex, as well as IntelliJ IDEA integration is also more tricky.

From point of view of future of C10N project, it is unlikely to be stongly dependent on Guice, and thus it make sense to make the separation more loose.

Multiple classloaders and thread safety

Hello!

I would love to use c10n in a project where I have several bundles in an OSGi environment.

I have seen the ticket in which you show how to have different configurations of c10n for different libraries, but in this case it is the classloader for c10n has to be set in every package to the classloader of that package.
I could use C10N.setProxyClassloader, but if between that call and the creation of the package's instance, another package in another thread is initializing its own instance of c10n, I don't think I'm guaranteed to get what I want.

Is this possible?

Loading locale-sensitive external resources

Inspired by https://developers.google.com/web-toolkit/doc/latest/DevGuideClientBundle#I18N

API draft:

@C10NMessages
public interface MyMessages{
  //locale mapped external file resources (or http, etc) 
  @En(extRes="file:///absolute/path/text.txt")
  @Ja(extRes="file://../relative/path/text.txt")
  String textFileContents();

  //Defer to ResourceBundle-like locale resolution 
  // (e.g. look for text_ja_JP.txt for Jp locale)
  @C10NResource(extRes="file://absolute/path/text.txt")
  String textFileContents2();

  //Access internal (in-the-jar) resources
  @En(intRes="com/example/text.txt")
  @C10NResource(intRes="com/example/text.txt")
  String internalResourceContents();
}

Fallback does not work when there is at least one non-fallback method declared

For example if @En is declared as fallback of @Ja:

void configure(){
  install(new DefaultC10NAnnotations());
  bindAnnotation(En.class); //define @En as fallback
}

Then with Locale set to "jp_ja", the following method greeting() will produce "Hello" (correct behaviour)

interface Greeting{
  @En("Hello")
  String greeting();
}

where as, in the following case it will output the internal fallback message "Greeting.greeting":

interface Greeting{
  @En("other")
  @Ja("other")
  String other();

  @En("Hello")
  String greeting();
}

Migrate to JDK8

Currently the library is built for use with Java6 (1.6), however, since my local development environment has been updated to JDK8 (and old JDKs removed), cross-compiling for older platforms may generate byte code that does not work correctly with the previous Java releases.

More information about this can be found here.

From 1.3, both source and binary will be updated for use with Java8 (1.8).

For those wishing to use c10n with the older versions, you will need to either:

  • Use c10n version 1.2 or earlier (compiled with JDK8, so no guarantees it will work)
  • Download old JDK, and compile c10n yourself. If you need long support for this, contact me and I will consider maintaining a backwards-compatible branch of c10n

c10n-tools depends on "c10n" but should be "c10n-core"

Could not build gradle deps on c10n-tools due to exception below:

* What went wrong:
A problem occurred evaluating project ':tools:dbMigration'.
> Could not resolve all dependencies for configuration ':tools:dbMigration:runtime'.
   > Could not find com.github.rodionmoiseev.c10n:c10n:1.2.
     Searched in the following locations:
         http://logst17.dev.infoscience.co.jp:8081/artifactory/public/com/github/rodionmoiseev/c10n/c10n/1.2/c10n-1.2.pom
         http://logst17.dev.infoscience.co.jp:8081/artifactory/public/com/github/rodionmoiseev/c10n/c10n/1.2/c10n-1.2.jar
         http://ginsim.org/maven/stable/com/github/rodionmoiseev/c10n/c10n/1.2/c10n-1.2.pom
         http://ginsim.org/maven/stable/com/github/rodionmoiseev/c10n/c10n/1.2/c10n-1.2.jar
         http://oss.sonatype.org/content/repositories/snapshots/com/github/rodionmoiseev/c10n/c10n/1.2/c10n-1.2.pom
         http://oss.sonatype.org/content/repositories/snapshots/com/github/rodionmoiseev/c10n/c10n/1.2/c10n-1.2.jar
     Required by:
         Logstorage-X.tools:dbMigration:2.2.0.8 > Logstorage-X.core:shared:2.2.0.8 > com.github.rodionmoiseev.c10n:c10n-tools:1.2

It seems that pom generated by gradle fail to set correct artifact name for c10n-core:

Should be "c10n-core", but actual value is "c10n" (the module name).

Make call to `configure` a requirement, and throw exception otherwise

It is sometimes easy to oversee a problem where C10N.configure() is not properly called before other c10n calls, especially when integrating c10n into other frameworks (see #17)

In order to prevent this, any call to C10N.get() should throw an exception if called prior to configure().

However, for compatibility reasons, there needs to be a way to suppress this behaviour (a system property should do for now)

Auto-resolving of external resources

Forked from issue #2

Implement a @C10NResource annotation to support the following construts.

@C10NMessages
public interface MyMessages{
  //Defer to ResourceBundle-like locale resolution 
  // (e.g. look for text_ja_JP.txt for Jp locale)
  @C10NResource(extRes="file://absolute/path/text.txt")
  String textFileContents2();

  //Access internal (in-the-jar) resources
  @C10NResource(intRes="com/example/text.txt")
  String internalResourceContents();
}

Support special `C10NMessage` return type containing all translation mapping

Idea taken from commit by @bartl Ákos to the akysoft fork.

The idea is to allow the user to retrieve translations for all locales, instead of just the value for the current locale. This can be done by declaring the method in the @C10NMessages interface with a special C10NMessage type (instead of a more typical String), as in the example below:

@C10NMessages
public interface Messages{
  @En("English")
  @Ja("Japanese")
  C10NMessage myMessage();
}

The appropriate information on available translations will be available in the C10NMessage class.

Create a logging plugin

With the new plugin system (See #31) it would be possible to perform logging, backed by a custom logging framework (e.g. Log4j, Logback, etc.)

@Logger("my-logger")
@C10NMessages
interface LoggingTest{

  /**
   * Optional explanation on what this log is.
   *
   * @param user Optional explanation by parameter
   */
  @En("User {0} has attempted to login from {1}")
  @Ja("{0}ユーザが{1}からログインしました")/*optional japanese*/
  @Level(INFO)
  @Custom("Add custom metadata like error-codes")
  void userLoginAttempt(String user, String ipAddress);

  @En("Something nasty happened")
  @Level(WARN)
  void oops(Throwable cause);
}

The above interface would be instantiated through c10n as usual, but would result in the message being logged to the given logger.

Additional annotations could be setup for each method to control logging behaviour, such as the logging level, logger name, or some custom MDC

{0} is not replaced with argument value

Hello. I configured C10N following way:

C10N.configure(new C10NConfigBase(){
            @Override
            public void configure(){
                install(new DefaultC10NAnnotations());
                setLocaleProvider(() -> Locale.ENGLISH);
            }
        });

and I've got following method:

@En("Can't load page by url {0}")
String pageNotLoaded(String url);

which returns Can't load page by url {0} instead of Can't load page by url MY_CUSTOM_URL

How can I fix it?

Create a plugin system for injecting custom logic at method eval-time

I want to make a plugin that would allow to log messages to a custom logger, with custom levels, when making a call to one of the c10n methods. For instance:

@C10NMessages
interface MyLogger{
  @En("Could not connect to {}")
  @Level(WARN)
  void aProblem(String ip);
}

The above should be doable with a simple plugin system that allows
to execute custom code when interface proxy method is executed.
Need to make sure the translations with placeholders are available
as well as any custom annotations (such as @Level above).

Make c10n available on maven central

Adding custom repositories to your pom file is possible and nice for open source projects. But it does not scale in the context of forced company repo proxies like nexus. So it would be nice to have the artefacts available on central. The process itself just a bit of work and not too complex. I already went through this so tell me if you need a helping hand on this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.