import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
-import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import org.opendaylight.controller.yang.model.api.SchemaPath;
import org.opendaylight.controller.yang.model.api.TypeDefinition;
import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition;
-import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition;
-import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit;
import org.opendaylight.controller.yang.model.api.type.DecimalTypeDefinition;
import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition;
import org.opendaylight.controller.yang.model.api.type.LengthConstraint;
import org.opendaylight.controller.yang.model.parser.builder.api.TypeDefinitionBuilder;
import org.opendaylight.controller.yang.model.parser.builder.impl.IdentitySchemaNodeBuilder;
import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;
+import org.opendaylight.controller.yang.model.parser.builder.impl.TypedefBuilder;
import org.opendaylight.controller.yang.model.parser.builder.impl.UnionTypeBuilder;
import org.opendaylight.controller.yang.model.parser.util.TypeConstraints;
import org.opendaylight.controller.yang.model.parser.util.YangParseException;
-import org.opendaylight.controller.yang.model.util.BinaryType;
-import org.opendaylight.controller.yang.model.util.BitsType;
-import org.opendaylight.controller.yang.model.util.StringType;
+import org.opendaylight.controller.yang.model.util.ExtendedType;
import org.opendaylight.controller.yang.model.util.UnknownType;
-import org.opendaylight.controller.yang.model.util.YangTypesConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
.getLogger(YangModelParserImpl.class);
@Override
- public Module parseYangModel(String yangFile) {
+ public Module parseYangModel(final String yangFile) {
final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFile);
- Set<Module> result = build(modules);
+ final Set<Module> result = build(modules);
return result.iterator().next();
}
@Override
- public Set<Module> parseYangModels(String... yangFiles) {
+ public Set<Module> parseYangModels(final String... yangFiles) {
final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFiles);
- Set<Module> result = build(modules);
- return result;
+ return build(modules);
}
@Override
public Set<Module> parseYangModelsFromStreams(
- InputStream... yangModelStreams) {
+ final InputStream... yangModelStreams) {
final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangModelStreams);
- Set<Module> result = build(modules);
- return result;
+ return build(modules);
}
@Override
- public SchemaContext resolveSchemaContext(Set<Module> modules) {
+ public SchemaContext resolveSchemaContext(final Set<Module> modules) {
return new SchemaContextImpl(modules);
}
private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
String... yangFiles) {
InputStream[] streams = new InputStream[yangFiles.length];
+ FileInputStream inStream = null;
for (int i = 0; i < yangFiles.length; i++) {
final String yangFileName = yangFiles[i];
final File yangFile = new File(yangFileName);
- FileInputStream inStream = null;
try {
inStream = new FileInputStream(yangFile);
} catch (FileNotFoundException e) {
final List<ParseTree> trees = parseStreams(yangFiles);
final ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
+ YangModelParserListenerImpl yangModelParser = null;
for (int i = 0; i < trees.size(); i++) {
- final YangModelParserListenerImpl yangModelParser = new YangModelParserListenerImpl();
+ yangModelParser = new YangModelParserListenerImpl();
walker.walk(yangModelParser, trees.get(i));
builders[i] = yangModelParser.getModuleBuilder();
}
}
private List<ParseTree> parseStreams(InputStream... yangStreams) {
- List<ParseTree> trees = new ArrayList<ParseTree>();
+ final List<ParseTree> trees = new ArrayList<ParseTree>();
for (InputStream yangStream : yangStreams) {
trees.add(parseStream(yangStream));
}
for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue()
.entrySet()) {
ModuleBuilder moduleBuilder = childEntry.getValue();
- validateBuilder(modules, moduleBuilder);
+ validateModule(modules, moduleBuilder);
}
}
+
// build
final Set<Module> result = new HashSet<Module>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue()
.entrySet()) {
ModuleBuilder moduleBuilder = childEntry.getValue();
- modulesByRevision.put(childEntry.getKey(),
- moduleBuilder.build());
- result.add(moduleBuilder.build());
+ Module module = moduleBuilder.build();
+ modulesByRevision.put(childEntry.getKey(), module);
+ result.add(module);
}
}
-
return result;
}
- private void validateBuilder(
+ private void validateModule(
Map<String, TreeMap<Date, ModuleBuilder>> modules,
ModuleBuilder builder) {
- resolveTypedefs(modules, builder);
+ resolveDirtyNodes(modules, builder);
resolveAugments(modules, builder);
resolveIdentities(modules, builder);
}
* @param module
* current module
*/
- private void resolveTypedefs(
+ private void resolveDirtyNodes(
Map<String, TreeMap<Date, ModuleBuilder>> modules,
ModuleBuilder module) {
- Map<List<String>, TypeAwareBuilder> dirtyNodes = module.getDirtyNodes();
- if (dirtyNodes.size() == 0) {
- return;
- } else {
+ final Map<List<String>, TypeAwareBuilder> dirtyNodes = module
+ .getDirtyNodes();
+ if (!dirtyNodes.isEmpty()) {
for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes
.entrySet()) {
- TypeAwareBuilder typeToResolve = entry.getValue();
+ TypeAwareBuilder typeToResolve = entry.getValue();
if (typeToResolve instanceof UnionTypeBuilder) {
- resolveUnionTypeBuilder(modules, module,
- (UnionTypeBuilder) typeToResolve);
+ UnionTypeBuilder union = (UnionTypeBuilder) typeToResolve;
+ List<TypeDefinition<?>> unionTypes = union.getTypes();
+ List<UnknownType> toRemove = new ArrayList<UnknownType>();
+ for (TypeDefinition<?> td : unionTypes) {
+ if (td instanceof UnknownType) {
+ UnknownType unknownType = (UnknownType) td;
+ TypeDefinitionBuilder resolvedType = findTargetTypeUnion(
+ typeToResolve, unknownType, modules, module);
+ union.setType(resolvedType);
+ toRemove.add(unknownType);
+ }
+ }
+ unionTypes.removeAll(toRemove);
} else {
- UnknownType ut = (UnknownType) typeToResolve.getType();
- TypeDefinition<?> resolvedType = findTargetType(ut,
- modules, module);
+ TypeDefinitionBuilder resolvedType = findTargetType(
+ typeToResolve, modules, module);
typeToResolve.setType(resolvedType);
}
}
}
}
- private UnionTypeBuilder resolveUnionTypeBuilder(
+ private TypeDefinitionBuilder findTargetType(
+ TypeAwareBuilder typeToResolve,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder) {
+ TypeConstraints constraints = new TypeConstraints();
+
+ TypeDefinitionBuilder targetType = findTypedef(typeToResolve, modules,
+ builder);
+ TypeConstraints tConstraints = findConstraints(typeToResolve,
+ constraints, modules, builder);
+ targetType.setRanges(tConstraints.getRange());
+ targetType.setLengths(tConstraints.getLength());
+ targetType.setPatterns(tConstraints.getPatterns());
+ targetType.setFractionDigits(tConstraints.getFractionDigits());
+
+ return targetType;
+ }
+
+ private TypeDefinitionBuilder findTargetTypeUnion(
+ TypeAwareBuilder typeToResolve, UnknownType unknownType,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder) {
+ TypeConstraints constraints = new TypeConstraints();
+
+ TypeDefinitionBuilder targetType = findTypedefUnion(typeToResolve,
+ unknownType, modules, builder);
+ TypeConstraints tConstraints = findConstraints(typeToResolve,
+ constraints, modules, builder);
+ targetType.setRanges(tConstraints.getRange());
+ targetType.setLengths(tConstraints.getLength());
+ targetType.setPatterns(tConstraints.getPatterns());
+ targetType.setFractionDigits(tConstraints.getFractionDigits());
+
+ return targetType;
+ }
+
+ private TypeDefinitionBuilder findTypedef(TypeAwareBuilder typeToResolve,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder) {
+
+ TypeDefinition<?> baseTypeToResolve = typeToResolve.getType();
+ if (baseTypeToResolve != null
+ && !(baseTypeToResolve instanceof UnknownType)) {
+ return (TypeDefinitionBuilder) typeToResolve;
+ }
+
+ UnknownType unknownType = (UnknownType) typeToResolve.getType();
+
+ QName unknownTypeQName = unknownType.getQName();
+ String unknownTypeName = unknownTypeQName.getLocalName();
+ String unknownTypePrefix = unknownTypeQName.getPrefix();
+
+ // search for module which contains referenced typedef
+ ModuleBuilder dependentModule = findDependentModule(modules, builder,
+ unknownTypePrefix);
+ TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
+ dependentModule.getModuleTypedefs(), unknownTypeName);
+
+ TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
+ lookedUpBuilder, typeToResolve instanceof TypeDefinitionBuilder);
+ TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
+ lookedUpBuilderCopy, modules, dependentModule);
+ return resolvedCopy;
+ }
+
+ private TypeDefinitionBuilder findTypedefUnion(
+ TypeAwareBuilder typeToResolve, UnknownType unknownType,
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- ModuleBuilder builder, UnionTypeBuilder unionTypeBuilderToResolve) {
- List<TypeDefinition<?>> resolvedTypes = new ArrayList<TypeDefinition<?>>();
- List<TypeDefinition<?>> typesToRemove = new ArrayList<TypeDefinition<?>>();
-
- for (TypeDefinition<?> td : unionTypeBuilderToResolve.getTypes()) {
- if (td instanceof UnknownType) {
- TypeDefinition<?> resolvedType = findTargetType(
- (UnknownType) td, modules, builder);
- resolvedTypes.add(resolvedType);
- typesToRemove.add(td);
+ ModuleBuilder builder) {
+
+ TypeDefinition<?> baseTypeToResolve = typeToResolve.getType();
+ if (baseTypeToResolve != null
+ && !(baseTypeToResolve instanceof UnknownType)) {
+ return (TypeDefinitionBuilder) typeToResolve;
+ }
+
+ QName unknownTypeQName = unknownType.getQName();
+ String unknownTypeName = unknownTypeQName.getLocalName();
+ String unknownTypePrefix = unknownTypeQName.getPrefix();
+
+ // search for module which contains referenced typedef
+ ModuleBuilder dependentModule = findDependentModule(modules, builder,
+ unknownTypePrefix);
+ TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
+ dependentModule.getModuleTypedefs(), unknownTypeName);
+
+ TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
+ lookedUpBuilder, typeToResolve instanceof TypeDefinitionBuilder);
+ TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
+ lookedUpBuilderCopy, modules, dependentModule);
+ return resolvedCopy;
+ }
+
+ private TypeDefinitionBuilder copyTypedefBuilder(TypeDefinitionBuilder old,
+ boolean seekByTypedefBuilder) {
+ if (old instanceof UnionTypeBuilder) {
+ UnionTypeBuilder oldUnion = (UnionTypeBuilder) old;
+ UnionTypeBuilder newUnion = new UnionTypeBuilder();
+ for (TypeDefinition<?> td : oldUnion.getTypes()) {
+ newUnion.setType(td);
+ }
+ for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) {
+ newUnion.setType(copyTypedefBuilder(tdb, true));
}
+ return newUnion;
}
- List<TypeDefinition<?>> unionTypeBuilderTypes = unionTypeBuilderToResolve
- .getTypes();
- unionTypeBuilderTypes.addAll(resolvedTypes);
- unionTypeBuilderTypes.removeAll(typesToRemove);
+ QName oldQName = old.getQName();
+ QName newQName = new QName(oldQName.getNamespace(),
+ oldQName.getRevision(), oldQName.getPrefix(),
+ oldQName.getLocalName());
+ TypeDefinitionBuilder tdb = new TypedefBuilder(newQName);
+
+ tdb.setRanges(old.getRanges());
+ tdb.setLengths(old.getLengths());
+ tdb.setPatterns(old.getPatterns());
- return unionTypeBuilderToResolve;
+ TypeDefinition<?> oldType = old.getType();
+ if (oldType == null) {
+ tdb.setType(old.getTypedef());
+ } else {
+ tdb.setType(oldType);
+ }
+
+ if (!seekByTypedefBuilder) {
+ tdb.setDescription(old.getDescription());
+ tdb.setReference(old.getReference());
+ tdb.setStatus(old.getStatus());
+ tdb.setDefaultValue(old.getDefaultValue());
+ tdb.setUnits(old.getUnits());
+ }
+ return tdb;
}
- private TypeDefinition<?> findTargetType(UnknownType ut,
+ private TypeDefinitionBuilder resolveCopiedBuilder(
+ TypeDefinitionBuilder copied,
Map<String, TreeMap<Date, ModuleBuilder>> modules,
ModuleBuilder builder) {
- TypeConstraints constraints = new TypeConstraints();
- // RANGE
- List<RangeConstraint> ranges = ut.getRangeStatements();
- constraints.addRanges(ranges);
- // LENGTH
- List<LengthConstraint> lengths = ut.getLengthStatements();
- constraints.addLengths(lengths);
- // PATTERN
- List<PatternConstraint> patterns = ut.getPatterns();
- constraints.addPatterns(patterns);
- // Fraction Digits
- Integer fractionDigits = ut.getFractionDigits();
-
- Map<TypeDefinitionBuilder, TypeConstraints> foundedTypeDefinitionBuilder = findTypeDefinitionBuilderWithConstraints(
- constraints, modules, ut, builder);
- TypeDefinitionBuilder targetType = foundedTypeDefinitionBuilder
- .entrySet().iterator().next().getKey();
-
- TypeDefinition<?> targetTypeBaseType = targetType.getBaseType();
- targetTypeBaseType = mergeConstraints(targetTypeBaseType, constraints,
- fractionDigits);
-
- return targetTypeBaseType;
+ if (copied instanceof UnionTypeBuilder) {
+ UnionTypeBuilder union = (UnionTypeBuilder) copied;
+ List<TypeDefinition<?>> unionTypes = union.getTypes();
+ List<UnknownType> toRemove = new ArrayList<UnknownType>();
+ for (TypeDefinition<?> td : unionTypes) {
+ if (td instanceof UnknownType) {
+ UnknownType unknownType = (UnknownType) td;
+ TypeDefinitionBuilder resolvedType = findTargetTypeUnion(
+ union, unknownType, modules, builder);
+ union.setType(resolvedType);
+ toRemove.add(unknownType);
+ }
+ }
+ unionTypes.removeAll(toRemove);
+
+ return union;
+ }
+
+ TypeDefinition<?> base = copied.getType();
+ TypeDefinitionBuilder baseTdb = copied.getTypedef();
+ if (base != null && !(base instanceof UnknownType)) {
+ return copied;
+ } else if (base instanceof UnknownType) {
+ UnknownType unknownType = (UnknownType) base;
+ QName unknownTypeQName = unknownType.getQName();
+ String unknownTypePrefix = unknownTypeQName.getPrefix();
+ ModuleBuilder dependentModule = findDependentModule(modules,
+ builder, unknownTypePrefix);
+ TypeDefinitionBuilder unknownTypeBuilder = findTypedef(copied,
+ modules, dependentModule);
+ copied.setType(unknownTypeBuilder);
+ return copied;
+ } else if (base == null && baseTdb != null) {
+ // make a copy of baseTypeDef and call again
+ TypeDefinitionBuilder baseTdbCopy = copyTypedefBuilder(baseTdb,
+ true);
+ TypeDefinitionBuilder baseTdbCopyResolved = resolveCopiedBuilder(
+ baseTdbCopy, modules, builder);
+ copied.setType(baseTdbCopyResolved);
+ return copied;
+ } else {
+ throw new IllegalStateException(
+ "TypeDefinitionBuilder in unexpected state");
+ }
}
- /**
- * Traverse through all referenced types chain until base YANG type is
- * founded.
- *
- * @param constraints
- * current type constraints
- * @param modules
- * all available modules
- * @param unknownType
- * unknown type
- * @param builder
- * current module
- * @return map, where key is type referenced and value is its constraints
- */
- private Map<TypeDefinitionBuilder, TypeConstraints> findTypeDefinitionBuilderWithConstraints(
- TypeConstraints constraints,
+ private TypeDefinitionBuilder findTypedef(QName unknownTypeQName,
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- UnknownType unknownType, ModuleBuilder builder) {
- Map<TypeDefinitionBuilder, TypeConstraints> result = new HashMap<TypeDefinitionBuilder, TypeConstraints>();
- QName unknownTypeQName = unknownType.getQName();
+ ModuleBuilder builder) {
+
String unknownTypeName = unknownTypeQName.getLocalName();
String unknownTypePrefix = unknownTypeQName.getPrefix();
// search for module which contains referenced typedef
- ModuleBuilder dependentModuleBuilder = findDependentModule(modules,
- builder, unknownTypePrefix);
+ ModuleBuilder dependentModule = findDependentModule(modules, builder,
+ unknownTypePrefix);
TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
- dependentModuleBuilder.getModuleTypedefs(), unknownTypeName);
+ dependentModule.getModuleTypedefs(), unknownTypeName);
+
+ TypeDefinitionBuilder copied = copyTypedefBuilder(lookedUpBuilder, true);
+ return copied;
+ }
+
+ private TypeConstraints findConstraints(TypeAwareBuilder typeToResolve,
+ TypeConstraints constraints,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder) {
+
+ // union type cannot be restricted
+ if (typeToResolve instanceof UnionTypeBuilder) {
+ return constraints;
+ }
// if referenced type is UnknownType again, search recursively with
// current constraints
- TypeDefinition<?> referencedType = lookedUpBuilder.getBaseType();
- if (referencedType instanceof UnknownType) {
+ TypeDefinition<?> referencedType = typeToResolve.getType();
+ if (referencedType == null) {
+ TypeDefinitionBuilder tdb = (TypeDefinitionBuilder) typeToResolve;
+ final List<RangeConstraint> ranges = tdb.getRanges();
+ constraints.addRanges(ranges);
+ final List<LengthConstraint> lengths = tdb.getLengths();
+ constraints.addLengths(lengths);
+ final List<PatternConstraint> patterns = tdb.getPatterns();
+ constraints.addPatterns(patterns);
+ final Integer fractionDigits = tdb.getFractionDigits();
+ constraints.setFractionDigits(fractionDigits);
+ return constraints;
+ } else if (referencedType instanceof ExtendedType) {
+ ExtendedType ext = (ExtendedType) referencedType;
+ final List<RangeConstraint> ranges = ext.getRanges();
+ constraints.addRanges(ranges);
+ final List<LengthConstraint> lengths = ext.getLengths();
+ constraints.addLengths(lengths);
+ final List<PatternConstraint> patterns = ext.getPatterns();
+ constraints.addPatterns(patterns);
+ final Integer fractionDigits = ext.getFractionDigits();
+ constraints.setFractionDigits(fractionDigits);
+ return findConstraints(
+ findTypedef(ext.getQName(), modules, builder), constraints,
+ modules, builder);
+ } else if (referencedType instanceof UnknownType) {
UnknownType unknown = (UnknownType) referencedType;
final List<RangeConstraint> ranges = unknown.getRangeStatements();
constraints.addLengths(lengths);
final List<PatternConstraint> patterns = unknown.getPatterns();
constraints.addPatterns(patterns);
- return findTypeDefinitionBuilderWithConstraints(constraints,
- modules, unknown, dependentModuleBuilder);
+ final Integer fractionDigits = unknown.getFractionDigits();
+ constraints.setFractionDigits(fractionDigits);
+
+ String unknownTypePrefix = unknown.getQName().getPrefix();
+ if (unknownTypePrefix == null || "".equals(unknownTypePrefix)) {
+ unknownTypePrefix = builder.getPrefix();
+ }
+ ModuleBuilder dependentModule = findDependentModule(modules,
+ builder, unknown.getQName().getPrefix());
+ TypeDefinitionBuilder unknownTypeBuilder = findTypedef(
+ unknown.getQName(), modules, builder);
+ return findConstraints(unknownTypeBuilder, constraints, modules,
+ dependentModule);
} else {
+ // HANDLE BASE YANG TYPE
mergeConstraints(referencedType, constraints);
- result.put(lookedUpBuilder, constraints);
- return result;
+ return constraints;
}
+
}
/**
}
/**
- * Merge curent constraints with founded type constraints
- *
- * @param targetTypeBaseType
- * @param constraints
- * @param fractionDigits
- * @return
- */
- private TypeDefinition<?> mergeConstraints(
- TypeDefinition<?> targetTypeBaseType, TypeConstraints constraints,
- Integer fractionDigits) {
- String targetTypeBaseTypeName = targetTypeBaseType.getQName()
- .getLocalName();
- // enumeration, leafref and identityref omitted because they have no
- // restrictions
- if (targetTypeBaseType instanceof DecimalTypeDefinition) {
- List<RangeConstraint> ranges = constraints.getRange();
- Integer fd = fractionDigits == null ? constraints
- .getFractionDigits() : fractionDigits;
- targetTypeBaseType = YangTypesConverter
- .javaTypeForBaseYangDecimal64Type(ranges, fd);
- } else if (targetTypeBaseType instanceof IntegerTypeDefinition) {
- List<RangeConstraint> ranges = constraints.getRange();
- if (targetTypeBaseTypeName.startsWith("int")) {
- targetTypeBaseType = YangTypesConverter
- .javaTypeForBaseYangSignedIntegerType(
- targetTypeBaseTypeName, ranges);
- } else {
- targetTypeBaseType = YangTypesConverter
- .javaTypeForBaseYangUnsignedIntegerType(
- targetTypeBaseTypeName, ranges);
- }
- } else if (targetTypeBaseType instanceof StringTypeDefinition) {
- List<LengthConstraint> lengths = constraints.getLength();
- List<PatternConstraint> patterns = constraints.getPatterns();
- targetTypeBaseType = new StringType(lengths, patterns);
- } else if (targetTypeBaseType instanceof BitsTypeDefinition) {
- BitsTypeDefinition bitsType = (BitsTypeDefinition) targetTypeBaseType;
- List<Bit> bits = bitsType.getBits();
- targetTypeBaseType = new BitsType(bits);
- } else if (targetTypeBaseType instanceof BinaryTypeDefinition) {
- List<LengthConstraint> lengths = constraints.getLength();
- List<Byte> bytes = Collections.emptyList();
- targetTypeBaseType = new BinaryType(bytes, lengths, null);
- }
- return targetTypeBaseType;
- }
-
- /**
- * Pull restriction from base type and add them to given constraints
+ * Pull restriction from referenced type and add them to given constraints
*
* @param referencedType
* @param constraints
}
private Date createEpochTime() {
- Calendar c = Calendar.getInstance();
- c.setTimeInMillis(0);
- return c.getTime();
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(0);
+ return calendar.getTime();
}
private static class SchemaContextImpl implements SchemaContext {