use of javax.annotation.processing.FilerException in project service-proxy by membrane.
the class BlueprintParsers method writeParsers.
public void writeParsers(Model m) throws IOException {
for (MainInfo main : m.getMains()) {
for (ElementInfo ii : main.getIis()) {
List<Element> sources = new ArrayList<Element>();
sources.add(main.getElement());
sources.add(ii.getElement());
String interceptorClassName = ii.getElement().getQualifiedName().toString();
try {
FileObject o = processingEnv.getFiler().createSourceFile(main.getAnnotation().outputPackage() + ".blueprint" + "." + ii.getParserClassSimpleName(), sources.toArray(new Element[0]));
BufferedWriter bw = new BufferedWriter(o.openWriter());
try {
bw.write("/* Copyright 2014 predic8 GmbH, www.predic8.com\r\n" + "\r\n" + " Licensed under the Apache License, Version 2.0 (the \"License\");\r\n" + " you may not use this file except in compliance with the License.\r\n" + " You may obtain a copy of the License at\r\n" + "\r\n" + " http://www.apache.org/licenses/LICENSE-2.0\r\n" + "\r\n" + " Unless required by applicable law or agreed to in writing, software\r\n" + " distributed under the License is distributed on an \"AS IS\" BASIS,\r\n" + " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n" + " See the License for the specific language governing permissions and\r\n" + " limitations under the License. */\r\n" + "\r\n" + "package " + main.getAnnotation().outputPackage() + ".blueprint;\r\n" + "\r\n" + "import com.predic8.membrane.annot.parser.BlueprintElementParser;\r\n" + "import com.predic8.membrane.annot.parser.BlueprintParser;\r\n" + "import org.apache.aries.blueprint.ParserContext;\r\n" + "import org.osgi.service.blueprint.reflect.Metadata;\r\n" + "import org.apache.aries.blueprint.mutable.MutableBeanMetadata;\r\n" + "import org.osgi.service.blueprint.reflect.BeanMetadata;\r\n" + "import org.w3c.dom.Element;\r\n" + "");
bw.write("\r\n" + "/**\r\n" + " * Automatically generated by " + BlueprintParsers.class.getName() + ".\r\n" + " */\r\n" + "public class " + ii.getParserClassSimpleName() + " extends BlueprintElementParser {\r\n" + " public Metadata parse(BlueprintParser globalParser, Element element, ParserContext context) {\r\n" + " MutableBeanMetadata mcm = context.createMetadata(MutableBeanMetadata.class);\r\n" + " mcm.setId(context.generateId());\r\n" + " mcm.setScope(BeanMetadata.SCOPE_SINGLETON);\r\n" + " mcm.setRuntimeClass(" + interceptorClassName + ".class);\r\n" + " applySpringInterfacePatches(context, " + interceptorClassName + ".class, mcm);\r\n" + "\r\n");
if (ii.isHasIdField())
bw.write(" setPropertyIfSet(context, \"id\", element, mcm);\r\n");
bw.write(" setIdIfNeeded(element, context, \"" + ii.getAnnotation().name() + "\");\r\n");
for (AttributeInfo ai : ii.getAis()) {
if (ai.getXMLName().equals("id"))
continue;
if (ai.isBeanReference(processingEnv.getTypeUtils())) {
if (!ai.isRequired())
bw.write(" if (element.hasAttribute(\"" + ai.getXMLName() + "\"))\r\n");
bw.write(" setPropertyReference(context, \"" + ai.getSpringName() + "\", element.getAttribute(\"" + ai.getXMLName() + "\"), mcm);\r\n");
} else {
bw.write(" setProperty" + (ai.isRequired() ? "" : "IfSet") + "(context, \"" + ai.getXMLName() + "\", \"" + ai.getSpringName() + "\", element, mcm" + (ai.isEnum(processingEnv.getTypeUtils()) ? ", true" : "") + ");\r\n");
}
if (ai.getXMLName().equals("name"))
bw.write(" element.removeAttribute(\"name\");\r\n");
}
if (ii.getOai() != null) {
bw.write(" setProperties(context, \"" + ii.getOai().getSpringName() + "\", element, mcm);\r\n");
}
if (ii.getTci() != null)
bw.write(" setProperty(context, mcm, \"" + ii.getTci().getPropertyName() + "\", element.getTextContent());\r\n");
else
bw.write(" parseChildren(element, context, mcm, globalParser);\r\n");
for (ChildElementInfo cei : ii.getCeis()) if (cei.isList() && cei.isRequired()) {
bw.write(" if (!isPropertySet(mcm, \"" + cei.getPropertyName() + "\"))\r\n");
bw.write(" throw new RuntimeException(\"Property '" + cei.getPropertyName() + "' is required, but none was defined (empty list).\");\r\n");
}
bw.write("" + " return mcm;\r\n");
bw.write(" }\r\n");
bw.write(" @Override\r\n" + " protected void handleChildObject(Element ele, ParserContext context, MutableBeanMetadata mcm, Class<?> clazz, Object child) {\r\n");
for (ChildElementInfo cei : ii.getCeis()) {
bw.write(" if (" + cei.getTypeDeclaration().getQualifiedName() + ".class.isAssignableFrom(clazz)) {\r\n");
if (cei.isList())
bw.write(" appendToListProperty(context, mcm, \"" + cei.getPropertyName() + "\"" + ", child);\r\n");
else
bw.write(" setProperty(context, mcm, \"" + cei.getPropertyName() + "\"" + ", child);\r\n");
bw.write(" } else \r\n");
}
bw.write(" {\r\n" + " throw new RuntimeException(\"Unknown child class \\\"\" + clazz + \"\\\".\");\r\n" + " }\r\n");
bw.write(" }\r\n");
bw.write("}\r\n" + "");
} finally {
bw.close();
}
} catch (FilerException e) {
if (e.getMessage().contains("Source file already created"))
return;
throw e;
}
}
}
}
use of javax.annotation.processing.FilerException in project service-proxy by membrane.
the class Parsers method writeParsers.
public void writeParsers(Model m) throws IOException {
for (MainInfo main : m.getMains()) {
for (ElementInfo ii : main.getIis()) {
List<Element> sources = new ArrayList<Element>();
sources.add(main.getElement());
sources.add(ii.getElement());
String interceptorClassName = ii.getElement().getQualifiedName().toString();
try {
FileObject o = processingEnv.getFiler().createSourceFile(main.getAnnotation().outputPackage() + "." + ii.getParserClassSimpleName(), sources.toArray(new Element[0]));
BufferedWriter bw = new BufferedWriter(o.openWriter());
try {
bw.write("/* Copyright 2012 predic8 GmbH, www.predic8.com\r\n" + "\r\n" + " Licensed under the Apache License, Version 2.0 (the \"License\");\r\n" + " you may not use this file except in compliance with the License.\r\n" + " You may obtain a copy of the License at\r\n" + "\r\n" + " http://www.apache.org/licenses/LICENSE-2.0\r\n" + "\r\n" + " Unless required by applicable law or agreed to in writing, software\r\n" + " distributed under the License is distributed on an \"AS IS\" BASIS,\r\n" + " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n" + " See the License for the specific language governing permissions and\r\n" + " limitations under the License. */\r\n" + "\r\n" + "package " + main.getAnnotation().outputPackage() + ";\r\n" + "\r\n" + "import org.w3c.dom.Element;\r\n" + "import org.springframework.beans.factory.xml.ParserContext;\r\n" + "import org.springframework.beans.factory.support.BeanDefinitionBuilder;\r\n");
if (!main.getAnnotation().outputPackage().equals("com.predic8.membrane.core.config.spring"))
bw.write("import com.predic8.membrane.core.config.spring.*;\r\n");
bw.write("\r\n" + "/**\r\n" + " * Automatically generated by " + Parsers.class.getName() + ".\r\n" + " */\r\n" + "public class " + ii.getParserClassSimpleName() + " extends AbstractParser {\r\n" + "\r\n" + " protected Class<?> getBeanClass(org.w3c.dom.Element element) {\r\n" + " return " + interceptorClassName + ".class;\r\n" + " }\r\n");
bw.write(" @Override\r\n" + " protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {\r\n");
if (ii.isHasIdField())
bw.write(" setPropertyIfSet(\"id\", element, builder);\r\n");
bw.write(" setIdIfNeeded(element, parserContext, \"" + ii.getAnnotation().name() + "\");\r\n");
for (AttributeInfo ai : ii.getAis()) {
if (ai.getXMLName().equals("id"))
continue;
if (ai.isBeanReference(processingEnv.getTypeUtils())) {
if (!ai.isRequired())
bw.write(" if (element.hasAttribute(\"" + ai.getXMLName() + "\"))\r\n");
bw.write(" builder.addPropertyReference(\"" + ai.getSpringName() + "\", element.getAttribute(\"" + ai.getXMLName() + "\"));\r\n");
} else {
bw.write(" setProperty" + (ai.isRequired() ? "" : "IfSet") + "(\"" + ai.getXMLName() + "\", \"" + ai.getSpringName() + "\", element, builder" + (ai.isEnum(processingEnv.getTypeUtils()) ? ", true" : "") + ");\r\n");
}
if (ai.getXMLName().equals("name"))
bw.write(" element.removeAttribute(\"name\");\r\n");
}
if (ii.getOai() != null) {
bw.write(" setProperties(\"" + ii.getOai().getSpringName() + "\", element, builder);\r\n");
}
for (ChildElementInfo cei : ii.getCeis()) if (cei.isList())
bw.write(" builder.addPropertyValue(\"" + cei.getPropertyName() + "\", new java.util.ArrayList<Object>());\r\n");
if (ii.getTci() != null)
bw.write(" builder.addPropertyValue(\"" + ii.getTci().getPropertyName() + "\", element.getTextContent());\r\n");
else
bw.write(" parseChildren(element, parserContext, builder);\r\n");
for (ChildElementInfo cei : ii.getCeis()) if (cei.isList() && cei.isRequired()) {
bw.write(" if (builder.getBeanDefinition().getPropertyValues().getPropertyValue(\"" + cei.getPropertyName() + "[0]\") == null)\r\n");
bw.write(" throw new RuntimeException(\"Property '" + cei.getPropertyName() + "' is required, but none was defined (empty list).\");\r\n");
}
bw.write(" }\r\n" + "");
bw.write("@Override\r\n" + "protected void handleChildObject(Element ele, ParserContext parserContext, BeanDefinitionBuilder builder, Class<?> clazz, Object child) {\r\n");
for (ChildElementInfo cei : ii.getCeis()) {
bw.write(" if (" + cei.getTypeDeclaration().getQualifiedName() + ".class.isAssignableFrom(clazz)) {\r\n" + " setProperty(builder, \"" + cei.getPropertyName() + "\"" + (cei.isList() ? "+\"[\"+ incrementCounter(builder, \"" + cei.getPropertyName() + "\") + \"]\" " : "") + ", child);\r\n" + " } else \r\n");
}
bw.write(" {\r\n" + " throw new RuntimeException(\"Unknown child class \\\"\" + clazz + \"\\\".\");\r\n" + " }\r\n");
bw.write("}\r\n");
bw.write("}\r\n" + "");
} finally {
bw.close();
}
} catch (FilerException e) {
if (e.getMessage().contains("Source file already created"))
return;
throw e;
}
}
}
}
use of javax.annotation.processing.FilerException in project T-MVP by north2016.
the class InstanceProcessor method process.
@Override
public void process(RoundEnvironment roundEnv, AnnotationProcessor mAbstractProcessor) {
String CLASS_NAME = "InstanceFactory";
TypeSpec.Builder tb = classBuilder(CLASS_NAME).addModifiers(PUBLIC, FINAL).addJavadoc("@ 实例化工厂 此类由apt自动生成");
MethodSpec.Builder methodBuilder1 = MethodSpec.methodBuilder("create").addAnnotation(MemoryCache.class).addJavadoc("@此方法由apt自动生成").returns(Object.class).addModifiers(PUBLIC, STATIC).addException(IllegalAccessException.class).addException(InstantiationException.class).addParameter(Class.class, "mClass");
List<ClassName> mList = new ArrayList<>();
CodeBlock.Builder blockBuilder = CodeBlock.builder();
// 括号开始
blockBuilder.beginControlFlow(" switch (mClass.getSimpleName())");
try {
for (TypeElement element : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(InstanceFactory.class))) {
mAbstractProcessor.mMessager.printMessage(Diagnostic.Kind.NOTE, "正在处理: " + element.toString());
if (!Utils.isValidClass(mAbstractProcessor.mMessager, element))
return;
ClassName currentType = ClassName.get(element);
if (mList.contains(currentType))
continue;
mList.add(currentType);
// String className = null;
// try {
// Class<?> clazz = element.getAnnotation(InstanceFactory.class).value();
// className = clazz.getCanonicalName();
// } catch (MirroredTypeException mte) {
// DeclaredType classTypeMirror = (DeclaredType) mte.getTypeMirror();
// TypeElement classTypeElement = (TypeElement) classTypeMirror.asElement();
// className = classTypeElement.getQualifiedName().toString();
// } catch (Exception e) {
// }
// if (className != null && !className.equals(InstanceFactory.class.getName())) {
// blockBuilder.addStatement("case $S: return new $T()", currentType.simpleName(), Utils.getType(className));//初始化Repository
// } else {
// 初始化Presenter
blockBuilder.addStatement("case $S: return new $T()", currentType.simpleName(), currentType);
// }
}
blockBuilder.addStatement("default: return mClass.newInstance()");
blockBuilder.endControlFlow();
methodBuilder1.addCode(blockBuilder.build());
tb.addMethod(methodBuilder1.build());
// 生成源代码
JavaFile javaFile = JavaFile.builder(Utils.PackageName, tb.build()).build();
// 在 app module/build/generated/source/apt 生成一份源代码
javaFile.writeTo(mAbstractProcessor.mFiler);
} catch (FilerException e) {
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
use of javax.annotation.processing.FilerException in project T-MVP by north2016.
the class ApiFactoryProcessor method process.
@Override
public void process(RoundEnvironment roundEnv, AnnotationProcessor mAbstractProcessor) {
String CLASS_NAME = "ApiFactory";
String DATA_ARR_CLASS = "DataArr";
TypeSpec.Builder tb = classBuilder(CLASS_NAME).addModifiers(PUBLIC, FINAL).addJavadoc("@ API工厂 此类由apt自动生成");
try {
for (TypeElement element : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(ApiFactory.class))) {
mAbstractProcessor.mMessager.printMessage(Diagnostic.Kind.NOTE, "正在处理: " + element.toString());
for (Element e : element.getEnclosedElements()) {
ExecutableElement executableElement = (ExecutableElement) e;
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(e.getSimpleName().toString()).addJavadoc("@此方法由apt自动生成").addModifiers(PUBLIC, STATIC);
if (TypeName.get(executableElement.getReturnType()).toString().contains(DATA_ARR_CLASS)) {
// 返回列表数据
methodBuilder.returns(ClassName.get("io.reactivex", "Flowable"));
Map<String, Object> params = new HashMap<>();
methodBuilder.addParameter(params.getClass(), "param");
ClassName apiUtil = ClassName.get("com.base.util", "ApiUtil");
ClassName C = ClassName.get("com", "C");
CodeBlock.Builder blockBuilder = CodeBlock.builder();
int len = executableElement.getParameters().size();
for (int i = 0; i < len; i++) {
VariableElement ep = executableElement.getParameters().get(i);
boolean isLast = i == len - 1;
String split = (isLast ? "" : ",");
switch(ep.getSimpleName().toString()) {
case "include":
blockBuilder.add("$L.getInclude(param)" + split, apiUtil);
break;
case "where":
blockBuilder.add("$L.getWhere(param)" + split, apiUtil);
break;
case "skip":
blockBuilder.add("$L.getSkip(param)" + split, apiUtil);
break;
case "limit":
blockBuilder.add("$L.PAGE_COUNT" + split, C);
break;
case "order":
blockBuilder.add("$L._CREATED_AT" + split, C);
break;
}
}
methodBuilder.addStatement("return $T.getInstance()" + ".service.$L($L)" + ".compose($T.io_main())", ClassName.get("com.api", "Api"), e.getSimpleName().toString(), blockBuilder.build().toString(), ClassName.get("com.base.util.helper", "RxSchedulers"));
tb.addMethod(methodBuilder.build());
} else {
// 返回普通数据
methodBuilder.returns(TypeName.get(executableElement.getReturnType()));
String paramsString = "";
for (VariableElement ep : executableElement.getParameters()) {
methodBuilder.addParameter(TypeName.get(ep.asType()), ep.getSimpleName().toString());
paramsString += ep.getSimpleName().toString() + ",";
}
methodBuilder.addStatement("return $T.getInstance()" + ".service.$L($L)" + ".compose($T.io_main())", ClassName.get("com.api", "Api"), e.getSimpleName().toString(), paramsString.substring(0, paramsString.length() - 1), ClassName.get("com.base.util.helper", "RxSchedulers"));
tb.addMethod(methodBuilder.build());
}
}
}
// 生成源代码
JavaFile javaFile = JavaFile.builder(Utils.PackageName, tb.build()).build();
// 在 app module/build/generated/source/apt 生成一份源代码
javaFile.writeTo(mAbstractProcessor.mFiler);
} catch (FilerException e) {
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
use of javax.annotation.processing.FilerException in project T-MVP by north2016.
the class RouterProcessor method process.
@Override
public void process(RoundEnvironment roundEnv, AnnotationProcessor mAbstractProcessor) {
String CLASS_NAME = "TRouter";
TypeSpec.Builder tb = classBuilder(CLASS_NAME).addModifiers(PUBLIC, FINAL).addJavadoc("@ 全局路由器 此类由apt自动生成");
FieldSpec extraField = FieldSpec.builder(ParameterizedTypeName.get(HashMap.class, String.class, Object.class), "mCurActivityExtra").addModifiers(Modifier.PUBLIC, Modifier.STATIC).build();
tb.addField(extraField);
MethodSpec.Builder methodBuilder1 = MethodSpec.methodBuilder("go").addJavadoc("@此方法由apt自动生成").addModifiers(PUBLIC, STATIC).addParameter(String.class, "name").addParameter(HashMap.class, "extra").addParameter(ClassName.get("android.view", "View"), "view");
MethodSpec.Builder methodBuilder2 = MethodSpec.methodBuilder("bind").addJavadoc("@此方法由apt自动生成").addModifiers(PUBLIC, STATIC).addParameter(ClassName.get("android.app", "Activity"), "mContext");
List<ClassName> mList = new ArrayList<>();
CodeBlock.Builder blockBuilderGo = CodeBlock.builder();
CodeBlock.Builder blockBuilderBind = CodeBlock.builder();
ClassName appClassName = ClassName.get("com", "App");
blockBuilderGo.addStatement("mCurActivityExtra=extra");
blockBuilderGo.addStatement("Activity mContext=$T.getAppContext().getCurActivity()", appClassName);
// 括号开始
blockBuilderGo.beginControlFlow(" switch (name)");
blockBuilderBind.addStatement("if(mCurActivityExtra==null) return");
// 括号开始
blockBuilderBind.beginControlFlow(" switch (mContext.getClass().getSimpleName())");
List<RouterActivityModel> mRouterActivityModels = new ArrayList<>();
try {
for (TypeElement element : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Router.class))) {
ClassName currentType = ClassName.get(element);
if (mList.contains(currentType))
continue;
mList.add(currentType);
RouterActivityModel mRouterActivityModel = new RouterActivityModel();
mRouterActivityModel.setElement(element);
mRouterActivityModel.setActionName(element.getAnnotation(Router.class).value());
List<Element> mExtraElements = new ArrayList<>();
List<String> mExtraElementKeys = new ArrayList<>();
for (Element childElement : element.getEnclosedElements()) {
SceneTransition mSceneTransitionAnnotation = childElement.getAnnotation(SceneTransition.class);
if (mSceneTransitionAnnotation != null) {
mRouterActivityModel.setSceneTransitionElementName(mSceneTransitionAnnotation.value());
mRouterActivityModel.setSceneTransitionElement(childElement);
}
Extra mExtraAnnotation = childElement.getAnnotation(Extra.class);
if (mExtraAnnotation != null) {
mExtraElementKeys.add(mExtraAnnotation.value());
mExtraElements.add(childElement);
}
}
mRouterActivityModel.setExtraElementKeys(mExtraElementKeys);
mRouterActivityModel.setExtraElements(mExtraElements);
boolean isNeedBind = (mExtraElementKeys != null && mExtraElementKeys.size() > 0 || mRouterActivityModel.getSceneTransitionElement() != null);
mRouterActivityModel.setNeedBind(isNeedBind);
mRouterActivityModels.add(mRouterActivityModel);
}
ClassName mActivityCompatName = ClassName.get("android.support.v4.app", "ActivityCompat");
ClassName mIntentClassName = ClassName.get("android.content", "Intent");
ClassName mActivityOptionsCompatName = ClassName.get("android.support.v4.app", "ActivityOptionsCompat");
for (RouterActivityModel item : mRouterActivityModels) {
// 1
blockBuilderGo.add("case $S: \n", item.getActionName());
if (item.isNeedBind())
// 1
blockBuilderBind.add("case $S: \n", item.getElement().getSimpleName());
if (item.getExtraElements() != null && item.getExtraElements().size() > 0) {
for (int i = 0; i < item.getExtraElements().size(); i++) {
Element mFiled = item.getExtraElements().get(i);
blockBuilderBind.add(// 1
"(($T)mContext)." + // 2
"$L" + // 3
"= ($T) " + // 4
"mCurActivityExtra.get(" + // 5
"$S);\n", // 1
item.getElement(), // 2
mFiled, // 3
mFiled, // 5
item.getExtraElementKeys().get(i));
// 5
}
}
if (item.getSceneTransitionElement() != null) {
blockBuilderGo.add(// 2
"$L.startActivity(mContext," + // 3
"\nnew $L(mContext," + // 4
"\n$L.class)," + // 5
"\n$T.makeSceneTransitionAnimation(" + // 6
"\nmContext,view," + // 7
"\n$S).toBundle());", // 2
mActivityCompatName, // 3
mIntentClassName, // 4
item.getElement(), // 5
mActivityOptionsCompatName, // 6
item.getSceneTransitionElementName());
blockBuilderBind.add(// 2
"$T.setTransitionName(" + // 3
"(($T)mContext).mViewBinding." + // 4
"$L, " + // 5
"$S);\n", // 2
ClassName.get("android.support.v4.view", "ViewCompat"), // 3
item.getElement(), // 4
item.getSceneTransitionElement(), // 5
item.getSceneTransitionElementName());
} else {
blockBuilderGo.add(// 2
"mContext.startActivity(" + // 3
"\nnew $L(mContext," + // 7
"\n$L.class));", // 3
mIntentClassName, // 4
item.getElement());
}
// 1
blockBuilderGo.addStatement("\nbreak");
// 1
if (item.isNeedBind())
blockBuilderBind.addStatement("break");
}
blockBuilderGo.addStatement("default: break");
blockBuilderGo.endControlFlow();
methodBuilder1.addCode(blockBuilderGo.build());
blockBuilderBind.addStatement("default: break");
blockBuilderBind.endControlFlow();
methodBuilder2.addCode(blockBuilderBind.build());
tb.addMethod(methodBuilder1.build());
tb.addMethod(methodBuilder2.build());
// 增加go(action)和go(action,extra):两个重载方法
tb.addMethod(MethodSpec.methodBuilder("go").addJavadoc("@此方法由apt自动生成").addModifiers(PUBLIC, STATIC).addParameter(String.class, "name").addParameter(HashMap.class, "extra").addCode("go(name,extra,null);\n").build());
tb.addMethod(MethodSpec.methodBuilder("go").addJavadoc("@此方法由apt自动生成").addModifiers(PUBLIC, STATIC).addParameter(String.class, "name").addCode("go(name,null,null);\n").build());
// 生成源代码
JavaFile javaFile = JavaFile.builder(Utils.PackageName, tb.build()).build();
// 在 app module/build/generated/source/apt 生成一份源代码
javaFile.writeTo(mAbstractProcessor.mFiler);
} catch (FilerException e) {
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Aggregations