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());
}
}
}
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());
}
}
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;
}
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();
}
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;
}
Aggregations