/* (non-Javadoc)
@see com.abubusoft.kripton.processor.core.ModelElementVisitor#visit(com.abubusoft.kripton.processor.sqlite.model.SQLiteDatabaseSchema, com.abubusoft.kripton.processor.core.ModelClass)
188377
@Override
	public void visit(SQLiteDatabaseSchema schema, SQLiteEntity entity) throws Exception {
		String classCursorName = PREFIX+entity.getSimpleName()+SUFFIX;		

		PackageElement pkg = elementUtils.getPackageOf(entity.getElement());
		String packageName = pkg.isUnnamed() ? "" : pkg.getQualifiedName().toString();
		
		ClassName className=TypeUtility.className(packageName,classCursorName);

		AnnotationProcessorUtilis.infoOnGeneratedClasses(BindDataSource.class, packageName, classCursorName);
		classBuilder = TypeSpec.classBuilder(classCursorName).addModifiers(Modifier.PUBLIC);

		// javadoc for class
		classBuilder.addJavadoc("<p>");
		classBuilder.addJavadoc("\nCursor implementation for entity <code>$L</code>\n", entity.getSimpleName());
		classBuilder.addJavadoc("</p>\n");
		JavadocUtility.generateJavadocGeneratedBy(classBuilder);
		classBuilder.addJavadoc(" @see $T\n", TypeUtility.className(entity.getElement().getQualifiedName().toString()));

		//@formatter:off
		FieldSpec fieldSpec = FieldSpec.builder(Cursor.class, "cursor", Modifier.PROTECTED)
				.addJavadoc("Cursor used to read database\n")
				.build();
		//@formatter:on
		classBuilder.addField(fieldSpec);
		
		// add constructor
		//@formatter:off
		classBuilder.addMethod(MethodSpec.constructorBuilder()
				.addJavadoc("<p>Constructor</p>\n\n")
				.addJavadoc("@param cursor cursor used to read from database\n")
				.addParameter(Cursor.class, "cursor")
				.addCode("wrap(cursor);\n")
				.build());
		//@formatter:on

		// add wrap method
		//@formatter:off
		MethodSpec.Builder wrapMethodBuilder = MethodSpec.methodBuilder("wrap")
				.addJavadoc("<p>Wrap cursor with this class</p>\n\n")
				.addJavadoc("@param cursor cursor to include\n")
				.addModifiers(Modifier.PUBLIC)
				.addParameter(Cursor.class, "cursor")
				.returns(className)
				.addCode("this.cursor=cursor;\n");
		//@formatter:on
		counter=0;
		wrapMethodBuilder.addCode("\n");
		for (SQLProperty item : entity.getCollection()) {
			wrapMethodBuilder.addCode("index$L=cursor.getColumnIndex($S);\n", counter, item.columnName);
			counter++;
		}
		wrapMethodBuilder.addCode("\n");
		wrapMethodBuilder.addCode("return this;\n");
		
		classBuilder.addMethod(wrapMethodBuilder.build());
		
		// add execute method		
		classBuilder.addMethod(generateExecuteMethod(packageName, entity).build());
		
		// add execute listener method
		classBuilder.addMethod(generateExecuteListener(packageName, entity).build());

		// add create
		//@formatter:off
		classBuilder.addMethod(
				MethodSpec.methodBuilder("create")
				.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
				.addParameter(Cursor.class, "cursor")
				.returns(className(packageName, classCursorName))
				.addJavadoc("<p>Create a binded cursor starting from a cursor</p>\n\n")
				.addJavadoc("@param cursor to wrap\n")
				.addCode("return new "+classCursorName+"(cursor);\n")				
				.build());
		//@formatter:on

		// define column typeName set
		counter=0;
		for (ModelProperty item : entity.getCollection()) {
			item.accept(this);
		}
		
		TypeSpec typeSpec = classBuilder.build();			
		JavaWriterHelper.writeJava2File(filer, packageName, typeSpec);

	}
944488
@Override
    public void visit(ClassOrInterfaceDeclaration declaration, ControllerModel controller) {
        controller.setName(declaration.getName());

        LOGGER.info("[controller]Visit " + controller.getName());
        //Go on with the methods and annotations
        super.visit(declaration,controller);
    }
783711
@Override
    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String exceptions[]) {
        if (scanPolicyIsExternal() || !isDetailEnabled()) {
            visitEnd();
            throw VISIT_ENDED_DETAIL;
        }

        return methodVisitor;
    }
425893
@Override
    public void visit(NodeVisitor v) {
        if (!v.visit(this)) {
            return;
        }
        result.visit(v);
        for (ArrayComprehensionLoop loop : loops) {
            loop.visit(v);
        }
        if (filter != null) {
            filter.visit(v);
        }
    }
320792
@Override
    public void visit(NodeVisitor v) {
        if (v.visit(this)) {
            if (namespace != null) {
                namespace.visit(v);
            }
            indexExpr.visit(v);
        }
    }
940935
@Override
	public void visit(SQLProperty kriptonProperty) {
		// @formatter:off
		FieldSpec fieldSpec = FieldSpec
				.builder(String.class, "COLUMN_" + columnNameToUpperCaseConverter.convert(kriptonProperty.getName()),
						Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
				.initializer("$S", kriptonProperty.columnName)
				.addJavadoc(
						"Entity's property <code>$L</code> is associated to table column <code>$L</code>. This costant represents column name.\n",
						kriptonProperty.getName(), kriptonProperty.columnName)
				.addJavadoc("\n @see $T#$L\n", kriptonProperty.getEntityTypeName(), kriptonProperty.getName()).build();
		// @formatter:on
		classBuilder.addField(fieldSpec);
	}
686949
@Override
    public void visit(NodeVisitor v) {
        if (v.visit(this)) {
            expression.visit(v);
            statement.visit(v);
        }
    }
35832
@Override
    public void visitClass(ClassDescriptor classDescriptor) throws CheckedAnalysisException {
        IAnalysisCache analysisCache = Global.getAnalysisCache();

        JavaClass jclass = analysisCache.getClassAnalysis(JavaClass.class, classDescriptor);
        classContext = analysisCache.getClassAnalysis(ClassContext.class, classDescriptor);

        for (Method m : classContext.getMethodsInCallOrder()) {
            if (m.getCode() == null) {
                continue;
            }
            method = m;

            MethodDescriptor methodDescriptor = BCELUtil.getMethodDescriptor(jclass, method);

            // Try to get MethodGen. If we can't get one,
            // then this method should be skipped.
            MethodGen methodGen = analysisCache.getMethodAnalysis(MethodGen.class, methodDescriptor);
            if (methodGen == null) {
                continue;
            }

            CFG cfg = analysisCache.getMethodAnalysis(CFG.class, methodDescriptor);
            visitMethodCFG(methodDescriptor, cfg);
        }
    }
370997
@Override
    public void visitMethod(final Method obj) {
        if (obj.isSynthetic()) {
            return;
        }
        ExceptionTable et = obj.getExceptionTable();
        if (et != null) {
            String[] exNames = et.getExceptionNames();
            Set<String> methodRTExceptions = new HashSet<>(6);
            int priority = LOW_PRIORITY;
            boolean foundRuntime = false;
            for (String ex : exNames) {
                boolean isRuntime = false;
                if (runtimeExceptions.contains(ex)) {
                    isRuntime = true;
                } else {
                    try {
                        JavaClass exClass = Repository.lookupClass(ex);
                        if (exClass.instanceOf(runtimeExceptionClass)) {
                            runtimeExceptions.add(ex);
                            if (ex.startsWith("java.lang.")) {
                                priority = NORMAL_PRIORITY;
                            }
                            isRuntime = true;
                        }
                    } catch (ClassNotFoundException cnfe) {
                        bugReporter.reportMissingClass(cnfe);
                    }
                }
                if (isRuntime) {
                    foundRuntime = true;
                    methodRTExceptions.add(ex);
                }
            }

            if (foundRuntime) {
                BugInstance bug = new BugInstance(this, BugType.DRE_DECLARED_RUNTIME_EXCEPTION.name(), priority).addClass(this).addMethod(this);

                for (String ex : methodRTExceptions) {
                    bug.add(new StringAnnotation(ex));
                }

                bugReporter.reportBug(bug);
            }
        }
    }
25183
@Override
	public void traverse(SchemaVisitor visitor) {
    	visitor.initialize(m_xsdpackageName, m_targetNamespace,m_classes);
    	for (Map.Entry<String,ObjectDescriptor> entry: m_elements.entrySet()) {
    		ObjectDescriptor objectDescriptor = entry.getValue();
    		// get the type and call the visitor for it.
    		objectDescriptor.traverse(visitor);
    	}
    	visitor.terminate();
    }
5484
static void query(SQLiteDatabase db, String conditions, QueryType type, OnResultListener listener) {
		String query = String.format(
				"SELECT name, sql FROM sqlite_master WHERE type='%s'and name!='sqlite_sequence' and name!='android_metadata'%s",
				type.toString().toLowerCase(), StringUtils.hasText(conditions) ? " AND " + conditions : "");
		try (Cursor cursor = db.rawQuery(query, null)) {
			if (cursor.moveToFirst()) {
				int index0 = cursor.getColumnIndex("name");
				int index1 = cursor.getColumnIndex("sql");
				do {
					listener.onRow(db, cursor.getString(index0), cursor.getString(index1));
				} while (cursor.moveToNext());
			}
		}
	}
35207
protected void onMissingTypeVisit(Table table, IndexField<?> field) {
        if (!Introspector.isModelClass(field.getType())) {
            return;
        }

        Field idField = Introspector.getOpenEngSBModelIdField(field.getType());

        if (idField == null) {
            LOG.warn("@Model class {} does not have an @OpenEngSBModelId", field.getType());
            return;
        }

        DataType type = getTypeMap().getType(idField.getType());

        if (type == null) {
            LOG.warn("@OpenEngSBModelId field {} has an unmapped type {}", field.getName(), field.getType());
            return;
        }

        ((JdbcIndexField) field).setMappedType(type);

        Column column = new Column(getColumnNameTranslator().translate(field), type);
        table.addElement(column); // will hold the models OID

        onAfterFieldVisit(table, column, field);
    }
940815
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            queryLocations = new ArrayList<>();
            loops = new ArrayList<>();
            super.visitClassContext(classContext);
        } finally {
            queryLocations = null;
            loops = null;
        }
    }
786100
@Override
    public Void visitClass(ClassTree node, Set<String> p) {
        scan(node.getModifiers(), p);
        scan(node.getTypeParameters(), p);
        scan(node.getExtendsClause(), p);
        scan(node.getImplementsClause(), p);
        scan(node.getMembers(), body);
        return null;
    }
148159
@Override
    public void visit(NodeVisitor v) {
        if (v.visit(this)) {
            for (ObjectProperty prop : getElements()) {
                prop.visit(v);
            }
        }
    }
1297338
@Override
    public void visit(NodeVisitor v) {
        if (v.visit(this)) {
            if (functionName != null) {
                functionName.visit(v);
            }
            for (AstNode param : getParams()) {
                param.visit(v);
            }
            getBody().visit(v);
            if (!isExpressionClosure) {
                if (memberExprNode != null) {
                    memberExprNode.visit(v);
                }
            }
        }
    }
299711
@Override
    public void visit(final int version, final int access, final String name,
            final String signature, final String superName,
            final String[] interfaces) {
        computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0;

        if (computeSVUID) {
            this.name = name;
            this.access = access;
            this.interfaces = new String[interfaces.length];
            System.arraycopy(interfaces, 0, this.interfaces, 0,
                    interfaces.length);
        }

        super.visit(version, access, name, signature, superName, interfaces);
    }