Search in sources :

Example 11 with LwRootContainer

use of com.intellij.uiDesigner.lw.LwRootContainer in project intellij-community by JetBrains.

the class Javac2 method instrumentForms.

/**
   * Instrument forms
   *
   * @param finder a classloader to use
   */
private void instrumentForms(final InstrumentationClassFinder finder) {
    // we instrument every file, because we cannot find which files should not be instrumented without dependency storage
    final ArrayList formsToInstrument = myFormFiles;
    if (formsToInstrument.size() == 0) {
        log("No forms to instrument found", Project.MSG_VERBOSE);
        return;
    }
    final HashMap class2form = new HashMap();
    for (int i = 0; i < formsToInstrument.size(); i++) {
        final File formFile = (File) formsToInstrument.get(i);
        log("compiling form " + formFile.getAbsolutePath(), Project.MSG_VERBOSE);
        final LwRootContainer rootContainer;
        try {
            rootContainer = Utils.getRootContainer(formFile.toURI().toURL(), new CompiledClassPropertiesProvider(finder.getLoader()));
        } catch (AlienFormFileException e) {
            // ignore non-IDEA forms
            continue;
        } catch (Exception e) {
            fireError("Cannot process form file " + formFile.getAbsolutePath() + ". Reason: " + e);
            continue;
        }
        final String classToBind = rootContainer.getClassToBind();
        if (classToBind == null) {
            continue;
        }
        String name = classToBind.replace('.', '/');
        File classFile = getClassFile(name);
        if (classFile == null) {
            log(formFile.getAbsolutePath() + ": Class to bind does not exist: " + classToBind, Project.MSG_WARN);
            continue;
        }
        final File alreadyProcessedForm = (File) class2form.get(classToBind);
        if (alreadyProcessedForm != null) {
            fireError(formFile.getAbsolutePath() + ": " + "The form is bound to the class " + classToBind + ".\n" + "Another form " + alreadyProcessedForm.getAbsolutePath() + " is also bound to this class.");
            continue;
        }
        class2form.put(classToBind, formFile);
        try {
            int version;
            InputStream stream = new FileInputStream(classFile);
            try {
                version = getClassFileVersion(new ClassReader(stream));
            } finally {
                stream.close();
            }
            AntNestedFormLoader formLoader = new AntNestedFormLoader(finder.getLoader(), myNestedFormPathList);
            InstrumenterClassWriter classWriter = new InstrumenterClassWriter(getAsmClassWriterFlags(version), finder);
            final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, finder, formLoader, false, classWriter);
            codeGenerator.patchFile(classFile);
            final FormErrorInfo[] warnings = codeGenerator.getWarnings();
            for (int j = 0; j < warnings.length; j++) {
                log(formFile.getAbsolutePath() + ": " + warnings[j].getErrorMessage(), Project.MSG_WARN);
            }
            final FormErrorInfo[] errors = codeGenerator.getErrors();
            if (errors.length > 0) {
                StringBuffer message = new StringBuffer();
                for (int j = 0; j < errors.length; j++) {
                    if (message.length() > 0) {
                        message.append("\n");
                    }
                    message.append(formFile.getAbsolutePath()).append(": ").append(errors[j].getErrorMessage());
                }
                fireError(message.toString());
            }
        } catch (Exception e) {
            fireError("Forms instrumentation failed for " + formFile.getAbsolutePath() + ": " + e.toString());
        }
    }
}
Also used : CompiledClassPropertiesProvider(com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider) LwRootContainer(com.intellij.uiDesigner.lw.LwRootContainer) MalformedURLException(java.net.MalformedURLException) BuildException(org.apache.tools.ant.BuildException) FailSafeClassReader(com.intellij.compiler.instrumentation.FailSafeClassReader) InstrumenterClassWriter(com.intellij.compiler.instrumentation.InstrumenterClassWriter)

Example 12 with LwRootContainer

use of com.intellij.uiDesigner.lw.LwRootContainer in project intellij-community by JetBrains.

the class Generator method generateDataBindingMethods.

/**
   * Should be invoked in command and write action
   */
@SuppressWarnings({ "HardCodedStringLiteral" })
public static void generateDataBindingMethods(final WizardData data) throws MyException {
    if (data.myBindToNewBean) {
        data.myBeanClass = createBeanClass(data);
    } else {
        if (!CommonRefactoringUtil.checkReadOnlyStatus(data.myBeanClass.getProject(), data.myBeanClass)) {
            return;
        }
    }
    final HashMap<String, String> binding2beanGetter = new HashMap<>();
    final HashMap<String, String> binding2beanSetter = new HashMap<>();
    final FormProperty2BeanProperty[] bindings = data.myBindings;
    for (final FormProperty2BeanProperty form2bean : bindings) {
        if (form2bean == null || form2bean.myBeanProperty == null) {
            continue;
        }
        // check that bean contains the property, and if not, try to add the property to the bean
        {
            final String setterName = PropertyUtil.suggestSetterName(form2bean.myBeanProperty.myName);
            final PsiMethod[] methodsByName = data.myBeanClass.findMethodsByName(setterName, true);
            if (methodsByName.length < 1) {
                // bean does not contain this property
                // try to add...
                // just generated bean class should contain all necessary properties
                LOG.assertTrue(!data.myBindToNewBean);
                if (!data.myBeanClass.isWritable()) {
                    throw new MyException("Cannot add property to non writable class " + data.myBeanClass.getQualifiedName());
                }
                final StringBuffer membersBuffer = new StringBuffer();
                final StringBuffer methodsBuffer = new StringBuffer();
                final Project project = data.myBeanClass.getProject();
                final CodeStyleManager formatter = CodeStyleManager.getInstance(project);
                final JavaCodeStyleManager styler = JavaCodeStyleManager.getInstance(project);
                generateProperty(styler, form2bean.myBeanProperty.myName, form2bean.myBeanProperty.myType, membersBuffer, methodsBuffer);
                final PsiClass fakeClass;
                try {
                    fakeClass = JavaPsiFacade.getInstance(data.myBeanClass.getProject()).getElementFactory().createClassFromText(membersBuffer.toString() + methodsBuffer.toString(), null);
                    final PsiField[] fields = fakeClass.getFields();
                    {
                        final PsiElement result = data.myBeanClass.add(fields[0]);
                        styler.shortenClassReferences(result);
                        formatter.reformat(result);
                    }
                    final PsiMethod[] methods = fakeClass.getMethods();
                    {
                        final PsiElement result = data.myBeanClass.add(methods[0]);
                        styler.shortenClassReferences(result);
                        formatter.reformat(result);
                    }
                    {
                        final PsiElement result = data.myBeanClass.add(methods[1]);
                        styler.shortenClassReferences(result);
                        formatter.reformat(result);
                    }
                } catch (IncorrectOperationException e) {
                    throw new MyException(e.getMessage());
                }
            }
        }
        final PsiMethod propertySetter = PropertyUtil.findPropertySetter(data.myBeanClass, form2bean.myBeanProperty.myName, false, true);
        final PsiMethod propertyGetter = PropertyUtil.findPropertyGetter(data.myBeanClass, form2bean.myBeanProperty.myName, false, true);
        if (propertyGetter == null) {
            // todo
            continue;
        }
        if (propertySetter == null) {
            // todo
            continue;
        }
        final String binding = form2bean.myFormProperty.getLwComponent().getBinding();
        binding2beanGetter.put(binding, propertyGetter.getName());
        binding2beanSetter.put(binding, propertySetter.getName());
    }
    final String dataBeanClassName = data.myBeanClass.getQualifiedName();
    final LwRootContainer[] rootContainer = new LwRootContainer[1];
    final FormProperty[] formProperties = exposeForm(data.myProject, data.myFormFile, rootContainer);
    final StringBuffer getDataBody = new StringBuffer();
    final StringBuffer setDataBody = new StringBuffer();
    final StringBuffer isModifiedBody = new StringBuffer();
    for (final FormProperty formProperty : formProperties) {
        final String binding = formProperty.getLwComponent().getBinding();
        if (!binding2beanGetter.containsKey(binding)) {
            continue;
        }
        getDataBody.append("data.");
        getDataBody.append(binding2beanSetter.get(binding));
        getDataBody.append("(");
        getDataBody.append(binding);
        getDataBody.append(".");
        getDataBody.append(formProperty.getComponentPropertyGetterName());
        getDataBody.append("());\n");
        setDataBody.append(binding);
        setDataBody.append(".");
        setDataBody.append(formProperty.getComponentPropertySetterName());
        setDataBody.append("(data.");
        setDataBody.append(binding2beanGetter.get(binding));
        setDataBody.append("());\n");
        final String propertyClassName = formProperty.getComponentPropertyClassName();
        if ("boolean".equals(propertyClassName)) {
            isModifiedBody.append("if (");
            //
            isModifiedBody.append(binding);
            isModifiedBody.append(".");
            isModifiedBody.append(formProperty.getComponentPropertyGetterName());
            isModifiedBody.append("()");
            //
            isModifiedBody.append("!= ");
            //
            isModifiedBody.append("data.");
            isModifiedBody.append(binding2beanGetter.get(binding));
            isModifiedBody.append("()");
            //
            isModifiedBody.append(") return true;\n");
        } else {
            isModifiedBody.append("if (");
            //
            isModifiedBody.append(binding);
            isModifiedBody.append(".");
            isModifiedBody.append(formProperty.getComponentPropertyGetterName());
            isModifiedBody.append("()");
            //
            isModifiedBody.append("!= null ? ");
            //
            isModifiedBody.append("!");
            //
            isModifiedBody.append(binding);
            isModifiedBody.append(".");
            isModifiedBody.append(formProperty.getComponentPropertyGetterName());
            isModifiedBody.append("()");
            //
            isModifiedBody.append(".equals(");
            //
            isModifiedBody.append("data.");
            isModifiedBody.append(binding2beanGetter.get(binding));
            isModifiedBody.append("()");
            isModifiedBody.append(") : ");
            //
            isModifiedBody.append("data.");
            isModifiedBody.append(binding2beanGetter.get(binding));
            isModifiedBody.append("()");
            isModifiedBody.append("!= null");
            //
            isModifiedBody.append(") return true;\n");
        }
    }
    isModifiedBody.append("return false;\n");
    final String textOfMethods = "public void setData(" + dataBeanClassName + " data){\n" + setDataBody.toString() + "}\n" + "\n" + "public void getData(" + dataBeanClassName + " data){\n" + getDataBody.toString() + "}\n" + "\n" + "public boolean isModified(" + dataBeanClassName + " data){\n" + isModifiedBody.toString() + "}\n";
    // put them to the bound class
    final Module module = ModuleUtil.findModuleForFile(data.myFormFile, data.myProject);
    LOG.assertTrue(module != null);
    final PsiClass boundClass = FormEditingUtil.findClassToBind(module, rootContainer[0].getClassToBind());
    LOG.assertTrue(boundClass != null);
    if (!CommonRefactoringUtil.checkReadOnlyStatus(module.getProject(), boundClass)) {
        return;
    }
    // todo: check that this method does not exist yet
    final PsiClass fakeClass;
    try {
        fakeClass = JavaPsiFacade.getInstance(data.myProject).getElementFactory().createClassFromText(textOfMethods, null);
        final PsiMethod methodSetData = fakeClass.getMethods()[0];
        final PsiMethod methodGetData = fakeClass.getMethods()[1];
        final PsiMethod methodIsModified = fakeClass.getMethods()[2];
        final PsiMethod existing1 = boundClass.findMethodBySignature(methodSetData, false);
        final PsiMethod existing2 = boundClass.findMethodBySignature(methodGetData, false);
        final PsiMethod existing3 = boundClass.findMethodBySignature(methodIsModified, false);
        // warning already shown
        if (existing1 != null) {
            existing1.delete();
        }
        if (existing2 != null) {
            existing2.delete();
        }
        if (existing3 != null) {
            existing3.delete();
        }
        final CodeStyleManager formatter = CodeStyleManager.getInstance(module.getProject());
        final JavaCodeStyleManager styler = JavaCodeStyleManager.getInstance(module.getProject());
        final PsiElement setData = boundClass.add(methodSetData);
        styler.shortenClassReferences(setData);
        formatter.reformat(setData);
        final PsiElement getData = boundClass.add(methodGetData);
        styler.shortenClassReferences(getData);
        formatter.reformat(getData);
        if (data.myGenerateIsModified) {
            final PsiElement isModified = boundClass.add(methodIsModified);
            styler.shortenClassReferences(isModified);
            formatter.reformat(isModified);
        }
        final OpenFileDescriptor descriptor = new OpenFileDescriptor(setData.getProject(), setData.getContainingFile().getVirtualFile(), setData.getTextOffset());
        FileEditorManager.getInstance(data.myProject).openTextEditor(descriptor, true);
    } catch (IncorrectOperationException e) {
        throw new MyException(e.getMessage());
    }
}
Also used : JavaCodeStyleManager(com.intellij.psi.codeStyle.JavaCodeStyleManager) CodeStyleManager(com.intellij.psi.codeStyle.CodeStyleManager) HashMap(java.util.HashMap) LwRootContainer(com.intellij.uiDesigner.lw.LwRootContainer) Project(com.intellij.openapi.project.Project) JavaCodeStyleManager(com.intellij.psi.codeStyle.JavaCodeStyleManager) IncorrectOperationException(com.intellij.util.IncorrectOperationException) OpenFileDescriptor(com.intellij.openapi.fileEditor.OpenFileDescriptor) Module(com.intellij.openapi.module.Module)

Example 13 with LwRootContainer

use of com.intellij.uiDesigner.lw.LwRootContainer in project intellij-community by JetBrains.

the class AsmCodeGeneratorTest method initCodeGenerator.

private AsmCodeGenerator initCodeGenerator(final String formFileName, final String className, final String testDataPath) throws Exception {
    String tmpPath = FileUtil.getTempDirectory();
    String formPath = testDataPath + formFileName;
    String javaPath = testDataPath + className + ".java";
    final int rc = Main.compile(new String[] { "-d", tmpPath, javaPath });
    assertEquals(0, rc);
    final String classPath = tmpPath + "/" + className + ".class";
    final File classFile = new File(classPath);
    assertTrue(classFile.exists());
    final LwRootContainer rootContainer = loadFormData(formPath);
    final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, myClassFinder, myNestedFormLoader, false, new ClassWriter(ClassWriter.COMPUTE_FRAMES));
    final FileInputStream classStream = new FileInputStream(classFile);
    try {
        codeGenerator.patchClass(classStream);
    } finally {
        classStream.close();
        FileUtil.delete(classFile);
        final File[] inners = new File(tmpPath).listFiles((dir, name) -> name.startsWith(className + "$") && name.endsWith(".class"));
        if (inners != null) {
            for (File file : inners) FileUtil.delete(file);
        }
    }
    return codeGenerator;
}
Also used : LwRootContainer(com.intellij.uiDesigner.lw.LwRootContainer) AsmCodeGenerator(com.intellij.uiDesigner.compiler.AsmCodeGenerator) ClassWriter(org.jetbrains.org.objectweb.asm.ClassWriter)

Example 14 with LwRootContainer

use of com.intellij.uiDesigner.lw.LwRootContainer in project intellij-community by JetBrains.

the class BaseFormInspection method checkFile.

@Override
@Nullable
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
    if (!file.getFileType().equals(StdFileTypes.GUI_DESIGNER_FORM)) {
        return null;
    }
    final VirtualFile virtualFile = file.getVirtualFile();
    if (virtualFile == null) {
        return null;
    }
    final Module module = ModuleUtil.findModuleForFile(virtualFile, file.getProject());
    if (module == null) {
        return null;
    }
    final LwRootContainer rootContainer;
    try {
        rootContainer = Utils.getRootContainer(file.getText(), new PsiPropertiesProvider(module));
    } catch (Exception e) {
        return null;
    }
    if (rootContainer.isInspectionSuppressed(getShortName(), null)) {
        return null;
    }
    final FormFileErrorCollector collector = new FormFileErrorCollector(file, manager, isOnTheFly);
    startCheckForm(rootContainer);
    FormEditingUtil.iterate(rootContainer, new FormEditingUtil.ComponentVisitor() {

        @Override
        public boolean visit(final IComponent component) {
            if (!rootContainer.isInspectionSuppressed(getShortName(), component.getId())) {
                checkComponentProperties(module, component, collector);
            }
            return true;
        }
    });
    doneCheckForm(rootContainer);
    return collector.result();
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) IComponent(com.intellij.uiDesigner.lw.IComponent) LwRootContainer(com.intellij.uiDesigner.lw.LwRootContainer) Module(com.intellij.openapi.module.Module) PsiPropertiesProvider(com.intellij.uiDesigner.PsiPropertiesProvider) FormEditingUtil(com.intellij.uiDesigner.FormEditingUtil) Nullable(org.jetbrains.annotations.Nullable)

Example 15 with LwRootContainer

use of com.intellij.uiDesigner.lw.LwRootContainer in project intellij-community by JetBrains.

the class BindingsCache method getBoundClassName.

public String getBoundClassName(final VirtualFile formFile) throws Exception {
    String classToBind = getSavedBinding(formFile);
    if (classToBind == null) {
        final Document doc = FileDocumentManager.getInstance().getDocument(formFile);
        final LwRootContainer rootContainer = Utils.getRootContainer(doc.getText(), null);
        classToBind = rootContainer.getClassToBind();
    }
    if (classToBind != null) {
        updateCache(formFile, classToBind);
    }
    return classToBind;
}
Also used : LwRootContainer(com.intellij.uiDesigner.lw.LwRootContainer) Document(com.intellij.openapi.editor.Document)

Aggregations

LwRootContainer (com.intellij.uiDesigner.lw.LwRootContainer)15 Module (com.intellij.openapi.module.Module)4 VirtualFile (com.intellij.openapi.vfs.VirtualFile)4 Project (com.intellij.openapi.project.Project)3 FormEditingUtil (com.intellij.uiDesigner.FormEditingUtil)3 PsiPropertiesProvider (com.intellij.uiDesigner.PsiPropertiesProvider)3 AlienFormFileException (com.intellij.uiDesigner.compiler.AlienFormFileException)3 CompiledClassPropertiesProvider (com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider)3 IncorrectOperationException (com.intellij.util.IncorrectOperationException)3 FailSafeClassReader (com.intellij.compiler.instrumentation.FailSafeClassReader)2 InstrumenterClassWriter (com.intellij.compiler.instrumentation.InstrumenterClassWriter)2 Document (com.intellij.openapi.editor.Document)2 JavaCodeStyleManager (com.intellij.psi.codeStyle.JavaCodeStyleManager)2 IComponent (com.intellij.uiDesigner.lw.IComponent)2 PsiGenerationInfo (com.intellij.codeInsight.generation.PsiGenerationInfo)1 WordOccurrence (com.intellij.lang.cacheBuilder.WordOccurrence)1 Editor (com.intellij.openapi.editor.Editor)1 OpenFileDescriptor (com.intellij.openapi.fileEditor.OpenFileDescriptor)1 PsiClass (com.intellij.psi.PsiClass)1 CodeStyleManager (com.intellij.psi.codeStyle.CodeStyleManager)1