Skip to content

Commit b6ab2a4

Browse files
committed
Issue #6.
1 parent b740747 commit b6ab2a4

13 files changed

Lines changed: 554 additions & 169 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.hisrc.jsonix.args4j;
2+
3+
import java.text.MessageFormat;
4+
import java.util.Locale;
5+
import java.util.ResourceBundle;
6+
7+
import org.kohsuke.args4j.Localizable;
8+
9+
public enum Messages implements Localizable {
10+
MISSING_OPERAND, UNDEFINED_OPTION, NO_ARGUMENT_ALLOWED, REQUIRED_OPTION_MISSING, TOO_MANY_ARGUMENTS, REQUIRED_ARGUMENT_MISSING, METADATA_ERROR, MULTIPLE_USE_OF_ARGUMENT, MULTIPLE_USE_OF_OPTION, UNKNOWN_HANDLER, NO_OPTIONHANDLER, NO_CONSTRUCTOR_ON_HANDLER, REQUIRES_OPTION_MISSING, FORBIDDEN_OPTION_PRESENT, NO_SUCH_FILE;
11+
12+
private static final String RESOURCE_BUNDLE_BASE_NAME = "org.kohsuke.args4j.Messages";
13+
14+
public String formatWithLocale(Locale locale, Object... args) {
15+
ResourceBundle localized = ResourceBundle.getBundle(
16+
RESOURCE_BUNDLE_BASE_NAME, locale);
17+
return MessageFormat.format(localized.getString(name()), args);
18+
}
19+
20+
public String format(Object... args) {
21+
return formatWithLocale(Locale.getDefault(), args);
22+
}
23+
}
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
package org.hisrc.jsonix.args4j;
2+
3+
import java.util.Arrays;
4+
import java.util.HashSet;
5+
import java.util.Set;
6+
7+
import org.apache.commons.lang3.Validate;
8+
import org.kohsuke.args4j.CmdLineException;
9+
import org.kohsuke.args4j.CmdLineParser;
10+
import org.kohsuke.args4j.NamedOptionDef;
11+
import org.kohsuke.args4j.ParserProperties;
12+
import org.kohsuke.args4j.spi.OptionHandler;
13+
import org.kohsuke.args4j.spi.Parameters;
14+
15+
public class PartialCmdLineParser extends CmdLineParser {
16+
17+
private OptionHandler<?> currentOptionHandler;
18+
19+
public PartialCmdLineParser(Object bean) {
20+
super(bean);
21+
}
22+
23+
public PartialCmdLineParser(Object bean, ParserProperties parserProperties) {
24+
super(bean, parserProperties);
25+
}
26+
27+
public int parseArgument(final String[] args, final int position)
28+
throws CmdLineException {
29+
Validate.noNullElements(args);
30+
currentOptionHandler = null;
31+
32+
CmdLineImpl cmdLine = new CmdLineImpl(args, position);
33+
34+
Set<OptionHandler<?>> present = new HashSet<OptionHandler<?>>();
35+
int argIndex = position;
36+
int consumed = 0;
37+
38+
while (cmdLine.hasMore()) {
39+
String arg = cmdLine.getCurrentToken();
40+
if (isOption(arg)) {
41+
// '=' is for historical compatibility fallback
42+
boolean isKeyValuePair = arg.contains(getProperties()
43+
.getOptionValueDelimiter()) || arg.indexOf('=') != -1;
44+
45+
// parse this as an option.
46+
currentOptionHandler = isKeyValuePair ? findOptionHandler(arg)
47+
: findOptionByName(arg);
48+
49+
if (currentOptionHandler == null) {
50+
return consumed;
51+
}
52+
53+
// known option; skip its name
54+
if (isKeyValuePair) {
55+
cmdLine.splitToken();
56+
} else {
57+
cmdLine.proceed(1);
58+
consumed++;
59+
}
60+
} else {
61+
if (argIndex >= getArguments().size()) {
62+
return consumed;
63+
}
64+
65+
// known argument
66+
currentOptionHandler = getArguments().get(argIndex);
67+
if (currentOptionHandler == null) // this is a programmer error.
68+
// arg index should be
69+
// continuous
70+
throw new IllegalStateException("@Argument with index="
71+
+ argIndex + " is undefined");
72+
73+
if (!currentOptionHandler.option.isMultiValued())
74+
argIndex++;
75+
}
76+
int diff = currentOptionHandler.parseArguments(cmdLine);
77+
cmdLine.proceed(diff);
78+
consumed += diff;
79+
present.add(currentOptionHandler);
80+
}
81+
82+
// check whether a help option is set
83+
boolean helpSet = false;
84+
for (OptionHandler<?> handler : getOptions()) {
85+
if (handler.option.help() && present.contains(handler)) {
86+
helpSet = true;
87+
}
88+
}
89+
90+
if (!helpSet) {
91+
checkRequiredOptionsAndArguments(present);
92+
}
93+
94+
return consumed;
95+
}
96+
97+
private OptionHandler<?> findOptionHandler(String name) {
98+
// Look for key/value pair first.
99+
int pos = name.indexOf(getProperties().getOptionValueDelimiter());
100+
if (pos < 0) {
101+
pos = name.indexOf('='); // historical compatibility fallback
102+
}
103+
if (pos > 0) {
104+
name = name.substring(0, pos);
105+
}
106+
return findOptionByName(name);
107+
}
108+
109+
private OptionHandler<?> findOptionByName(String name) {
110+
for (OptionHandler<?> h : getOptions()) {
111+
NamedOptionDef option = (NamedOptionDef) h.option;
112+
if (name.equals(option.name())) {
113+
return h;
114+
}
115+
for (String alias : option.aliases()) {
116+
if (name.equals(alias)) {
117+
return h;
118+
}
119+
}
120+
}
121+
return null;
122+
}
123+
124+
private void checkRequiredOptionsAndArguments(Set<OptionHandler<?>> present)
125+
throws CmdLineException {
126+
// make sure that all mandatory options are present
127+
for (OptionHandler<?> handler : getOptions()) {
128+
if (handler.option.required() && !present.contains(handler)) {
129+
throw new CmdLineException(this,
130+
Messages.REQUIRED_OPTION_MISSING,
131+
handler.option.toString());
132+
}
133+
}
134+
135+
// make sure that all mandatory arguments are present
136+
for (OptionHandler<?> handler : getOptions()) {
137+
if (handler.option.required() && !present.contains(handler)) {
138+
throw new CmdLineException(this,
139+
Messages.REQUIRED_ARGUMENT_MISSING,
140+
handler.option.toString());
141+
}
142+
}
143+
144+
// make sure that all requires arguments are present
145+
for (OptionHandler<?> handler : present) {
146+
if (handler.option instanceof NamedOptionDef
147+
&& !isHandlerHasHisOptions((NamedOptionDef) handler.option,
148+
present)) {
149+
throw new CmdLineException(this,
150+
Messages.REQUIRES_OPTION_MISSING,
151+
handler.option.toString(),
152+
Arrays.toString(((NamedOptionDef) handler.option)
153+
.depends()));
154+
}
155+
}
156+
157+
// make sure that all forbids arguments are not present
158+
for (OptionHandler<?> handler : present) {
159+
if (handler.option instanceof NamedOptionDef
160+
&& !isHandlerAllowOtherOptions(
161+
(NamedOptionDef) handler.option, present)) {
162+
throw new CmdLineException(this,
163+
Messages.FORBIDDEN_OPTION_PRESENT,
164+
handler.option.toString(),
165+
Arrays.toString(((NamedOptionDef) handler.option)
166+
.forbids()));
167+
}
168+
}
169+
}
170+
171+
private boolean isHandlerHasHisOptions(NamedOptionDef option,
172+
Set<OptionHandler<?>> present) {
173+
for (String depend : option.depends()) {
174+
if (!present.contains(findOptionHandler(depend)))
175+
return false;
176+
}
177+
return true;
178+
}
179+
180+
private boolean isHandlerAllowOtherOptions(NamedOptionDef option,
181+
Set<OptionHandler<?>> present) {
182+
for (String forbid : option.forbids()) {
183+
if (present.contains(findOptionHandler(forbid)))
184+
return false;
185+
}
186+
return true;
187+
}
188+
189+
private class CmdLineImpl implements Parameters {
190+
private final String[] args;
191+
private int pos;
192+
193+
CmdLineImpl(String[] args, int position) {
194+
this.args = args;
195+
pos = position;
196+
}
197+
198+
protected boolean hasMore() {
199+
return pos < args.length;
200+
}
201+
202+
protected String getCurrentToken() {
203+
return args[pos];
204+
}
205+
206+
private void proceed(int n) {
207+
pos += n;
208+
}
209+
210+
public String getParameter(int idx) throws CmdLineException {
211+
if (pos + idx >= args.length || pos + idx < 0)
212+
throw new CmdLineException(PartialCmdLineParser.this,
213+
Messages.MISSING_OPERAND, getOptionName());
214+
return args[pos + idx];
215+
}
216+
217+
public int size() {
218+
return args.length - pos;
219+
}
220+
221+
/**
222+
* Used when the current token is of the form "-option=value", to
223+
* replace the current token by "value", as if this was given as two
224+
* tokens "-option value"
225+
*/
226+
void splitToken() {
227+
if (pos < args.length && pos >= 0) {
228+
int idx = args[pos].indexOf("=");
229+
if (idx > 0) {
230+
args[pos] = args[pos].substring(idx + 1);
231+
}
232+
}
233+
}
234+
}
235+
236+
private String getOptionName() {
237+
return currentOptionHandler.option.toString();
238+
}
239+
}

compiler/src/main/java/org/hisrc/jsonix/configuration/ModulesConfigurationUnmarshaller.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
public class ModulesConfigurationUnmarshaller {
5454

5555
private final Logger logger;
56+
@SuppressWarnings("unused")
5657
private final JsonixContext context;
5758
private final JAXBContext jaxbContext;
5859

compiler/src/main/java/org/hisrc/jsonix/context/DefaultJsonixContext.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.hisrc.jsonix.context;
22

3-
import org.apache.commons.lang3.Validate;
43
import org.hisrc.jsonix.settings.LogLevelSetting;
54
import org.hisrc.jsonix.slf4j.LevelledLoggerFactoryWrapper;
65
import org.slf4j.ILoggerFactory;
@@ -14,7 +13,7 @@ public DefaultJsonixContext(ILoggerFactory loggerFactory) {
1413
this.loggerFactory = new LevelledLoggerFactoryWrapper(loggerFactory) {
1514
@Override
1615
protected int getLevel() {
17-
return DefaultJsonixContext.this.getLevelInt();
16+
return DefaultJsonixContext.this.getLogLevel();
1817
}
1918
};
2019
}
@@ -23,15 +22,14 @@ public DefaultJsonixContext() {
2322
this(LoggerFactory.getILoggerFactory());
2423
}
2524

26-
private int levelInt = LogLevelSetting.INFO.asInt();
25+
private int logLevel = LogLevelSetting.INFO.asInt();
2726

28-
protected int getLevelInt() {
29-
return 1;
27+
protected int getLogLevel() {
28+
return logLevel;
3029
}
3130

32-
public void setLevel(LogLevelSetting level) {
33-
Validate.notNull(level);
34-
this.levelInt = level.asInt();
31+
public void setLogLevel(int level) {
32+
this.logLevel = level;
3533
}
3634

3735
@Override

compiler/src/main/java/org/hisrc/jsonix/execution/JsonixInvoker.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
import org.hisrc.jsonix.compilation.ProgramWriter;
55
import org.hisrc.jsonix.configuration.ModulesConfiguration;
66
import org.hisrc.jsonix.configuration.ModulesConfigurationUnmarshaller;
7-
import org.hisrc.jsonix.context.JsonixContext;
7+
import org.hisrc.jsonix.configuration.OutputConfiguration;
8+
import org.hisrc.jsonix.context.DefaultJsonixContext;
89
import org.hisrc.jsonix.definition.Modules;
910
import org.hisrc.jsonix.settings.Settings;
1011
import org.jvnet.jaxb2_commons.xjc.model.concrete.XJCCMInfoFactory;
@@ -16,13 +17,22 @@
1617

1718
public class JsonixInvoker {
1819

19-
public void execute(JsonixContext context, Settings settings, Model model, ProgramWriter<NType, NClass> programWriter)
20-
{
20+
public void execute(Settings settings, Model model,
21+
ProgramWriter<NType, NClass> programWriter) {
22+
23+
final DefaultJsonixContext context = new DefaultJsonixContext();
24+
25+
context.setLogLevel(settings.getLogLevel().asInt());
26+
2127
final ModulesConfigurationUnmarshaller customizationHandler = new ModulesConfigurationUnmarshaller(
2228
context);
2329

30+
final OutputConfiguration defaultOutputConfiguration = new OutputConfiguration(
31+
settings.getDefaultNaming().getName(),
32+
OutputConfiguration.STANDARD_FILE_NAME_PATTERN);
33+
2434
final ModulesConfiguration modulesConfiguration = customizationHandler
25-
.unmarshal(model, this.defaultOutputConfiguration);
35+
.unmarshal(model, defaultOutputConfiguration);
2636

2737
final MModelInfo<NType, NClass> modelinfo = new XJCCMInfoFactory(model)
2838
.createModel();
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
package org.hisrc.jsonix.settings;
22

33
import org.hisrc.jsonix.naming.CompactNaming;
4-
import org.hisrc.jsonix.naming.Naming;
54
import org.hisrc.jsonix.naming.StandardNaming;
65

76
public enum NamingSetting {
87

9-
COMPACT(new CompactNaming()), STANDARD(new StandardNaming());
8+
COMPACT(CompactNaming.NAMING_NAME), STANDARD(StandardNaming.NAMING_NAME);
109

11-
private final Naming naming;
10+
private final String name;
1211

13-
private NamingSetting(Naming naming) {
14-
this.naming = naming;
12+
private NamingSetting(String naming) {
13+
this.name = naming;
1514
}
1615

17-
public Naming getNaming() {
18-
return this.naming;
16+
public String getName() {
17+
return this.name;
1918
}
2019
}

0 commit comments

Comments
 (0)