use of com.intellij.psi.PsiManager in project android by JetBrains.
the class LayoutMetadata method setProperty.
/**
* Sets the given property of the given DOM node to a given value, or if null clears
* the property.
*/
public static void setProperty(@NotNull final Project project, @Nullable String title, @NotNull final XmlFile file, @NotNull final XmlTag element, @NotNull final String name, @Nullable final String namespace, @Nullable final String value) {
String capitalizedName = StringUtil.capitalize(name);
if (title == null) {
title = String.format(value != null ? "Set %1$s" : "Clear %1$s", capitalizedName);
}
WriteCommandAction<Void> action = new WriteCommandAction<Void>(project, title, file) {
@Override
protected void run(@NotNull Result<Void> result) throws Throwable {
if (value == null) {
// Clear attribute
XmlAttribute attribute;
if (namespace != null) {
attribute = element.getAttribute(name, namespace);
} else {
attribute = element.getAttribute(name);
}
if (attribute != null) {
attribute.delete();
}
} else {
if (namespace != null) {
AndroidResourceUtil.ensureNamespaceImported(file, namespace, null);
element.setAttribute(name, namespace, value);
} else {
element.setAttribute(name, value);
}
}
}
};
action.execute();
// Also set the values on the same elements in any resource variations
// of the same layout
// TODO: This should be done after a brief delay, say 50ms
final List<XmlTag> list = ApplicationManager.getApplication().runReadAction(new Computable<List<XmlTag>>() {
@Override
@Nullable
public List<XmlTag> compute() {
// Look up the id of the element, if any
String id = stripIdPrefix(element.getAttributeValue(ATTR_ID, ANDROID_URI));
if (id.isEmpty()) {
return null;
}
VirtualFile layoutFile = file.getVirtualFile();
if (layoutFile != null) {
final List<VirtualFile> variations = ResourceHelper.getResourceVariations(layoutFile, false);
if (variations.isEmpty()) {
return null;
}
PsiManager manager = PsiManager.getInstance(project);
List<XmlTag> list = Lists.newArrayList();
for (VirtualFile file : variations) {
PsiFile psiFile = manager.findFile(file);
if (psiFile == null) {
continue;
}
for (XmlTag tag : PsiTreeUtil.findChildrenOfType(psiFile, XmlTag.class)) {
XmlAttribute attribute = tag.getAttribute(ATTR_ID, ANDROID_URI);
if (attribute == null || attribute.getValue() == null) {
continue;
}
if (attribute.getValue().endsWith(id) && id.equals(stripIdPrefix(attribute.getValue()))) {
list.add(tag);
break;
}
}
}
return list;
}
return null;
}
});
if (list != null && !list.isEmpty()) {
List<PsiFile> affectedFiles = Lists.newArrayList();
for (XmlTag tag : list) {
PsiFile psiFile = tag.getContainingFile();
if (psiFile != null) {
affectedFiles.add(psiFile);
}
}
action = new WriteCommandAction<Void>(project, title, affectedFiles.toArray(new PsiFile[affectedFiles.size()])) {
@Override
protected void run(@NotNull Result<Void> result) throws Throwable {
for (XmlTag tag : list) {
if (value == null) {
// Clear attribute
XmlAttribute attribute;
if (namespace != null) {
attribute = tag.getAttribute(name, namespace);
} else {
attribute = tag.getAttribute(name);
}
if (attribute != null) {
attribute.delete();
}
} else {
if (namespace != null) {
AndroidResourceUtil.ensureNamespaceImported(file, namespace, null);
tag.setAttribute(name, namespace, value);
} else {
tag.setAttribute(name, value);
}
}
}
}
};
action.execute();
}
}
use of com.intellij.psi.PsiManager in project android by JetBrains.
the class ModuleClassLoader method isSourceModified.
/**
* Determines whether the class specified by the given qualified name has a source file in the IDE that
* has been edited more recently than its corresponding class file.
* <p/>This method requires the indexing to have finished
* <p/><b>Note that this method can only answer queries for classes that this class loader has previously
* loaded!</b>
*
* @param fqcn the fully qualified class name
* @param myCredential a render sandbox credential
* @return true if the source file has been modified, or false if not (or if the source file cannot be found)
*/
public boolean isSourceModified(@NotNull final String fqcn, @Nullable final Object myCredential) {
final Module module = myModuleReference.get();
if (module == null) {
return false;
}
VirtualFile classFile = getClassFile(fqcn);
// Make sure the class file is up to date and if not, log an error
if (classFile != null) {
// Allow creating class loaders during rendering; may be prevented by the RenderSecurityManager
boolean token = RenderSecurityManager.enterSafeRegion(myCredential);
try {
long classFileModified = classFile.getTimeStamp();
if (classFileModified > 0L) {
VirtualFile virtualFile = ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile>() {
@Nullable
@Override
public VirtualFile compute() {
Project project = module.getProject();
GlobalSearchScope scope = module.getModuleWithDependenciesScope();
PsiManager psiManager = PsiManager.getInstance(project);
JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(psiManager.getProject());
PsiClass source = psiFacade.findClass(fqcn, scope);
if (source != null) {
PsiFile containingFile = source.getContainingFile();
if (containingFile != null) {
return containingFile.getVirtualFile();
}
}
return null;
}
});
if (virtualFile != null && !FN_RESOURCE_CLASS.equals(virtualFile.getName())) {
// Don't flag R.java edits; not done by user
// Edited but not yet saved?
boolean modified = FileDocumentManager.getInstance().isFileModified(virtualFile);
if (!modified) {
// Check timestamp
File sourceFile = VfsUtilCore.virtualToIoFile(virtualFile);
long sourceFileModified = sourceFile.lastModified();
AndroidFacet facet = AndroidFacet.getInstance(module);
// User modifications on the source file might not always result on a new .class file.
// We use the project modification time instead to display the warning more reliably.
// Also, some build systems may use a constant last modified timestamp for .class files,
// for deterministic builds, so the project modification time is more reliable.
long lastBuildTimestamp = classFileModified;
if (facet != null && facet.requiresAndroidModel() && facet.getAndroidModel() != null) {
Long projectBuildTimestamp = facet.getAndroidModel().getLastBuildTimestamp(module.getProject());
if (projectBuildTimestamp != null) {
lastBuildTimestamp = projectBuildTimestamp;
}
}
if (sourceFileModified > lastBuildTimestamp && lastBuildTimestamp > 0L) {
modified = true;
}
}
return modified;
}
}
} finally {
RenderSecurityManager.exitSafeRegion(token);
}
}
return false;
}
use of com.intellij.psi.PsiManager in project android by JetBrains.
the class NonAndroidSourceTypeNode method getChildren.
@NotNull
@Override
public Collection<? extends AbstractTreeNode> getChildren() {
List<VirtualFile> sourceFolders = getSourceFolders();
List<AbstractTreeNode> children = Lists.newArrayListWithExpectedSize(sourceFolders.size());
PsiManager psiManager = PsiManager.getInstance(myProject);
ProjectViewDirectoryHelper directoryHelper = ProjectViewDirectoryHelper.getInstance(myProject);
for (VirtualFile file : sourceFolders) {
PsiDirectory dir = psiManager.findDirectory(file);
if (dir != null) {
children.addAll(directoryHelper.getDirectoryChildren(dir, getSettings(), true));
}
}
return children;
}
use of com.intellij.psi.PsiManager in project android by JetBrains.
the class NativeAndroidLibraryNode method getDirectories.
@NotNull
@Override
public PsiDirectory[] getDirectories() {
PsiManager psiManager = PsiManager.getInstance(myProject);
List<PsiDirectory> psiDirectories = new ArrayList<>();
for (NativeArtifact artifact : getArtifacts()) {
for (VirtualFile f : getSourceFolders(artifact)) {
PsiDirectory dir = psiManager.findDirectory(f);
if (dir != null) {
psiDirectories.add(dir);
}
}
}
return psiDirectories.toArray(new PsiDirectory[psiDirectories.size()]);
}
use of com.intellij.psi.PsiManager in project android by JetBrains.
the class NativeAndroidLibraryNode method getSourceDirectoryNodes.
@NotNull
public static Collection<AbstractTreeNode> getSourceDirectoryNodes(@NotNull Project project, @NotNull Collection<NativeArtifact> artifacts, @NotNull ViewSettings settings, @NotNull Collection<String> sourceFileExtensions) {
TreeMap<String, RootDirectory> rootDirectories = new TreeMap<>();
for (NativeArtifact artifact : artifacts) {
addSourceFolders(rootDirectories, artifact);
addSourceFiles(rootDirectories, artifact);
}
if (rootDirectories.size() > 1) {
groupDirectories(rootDirectories);
}
if (rootDirectories.size() > 1) {
mergeDirectories(rootDirectories);
}
Set<String> fileExtensions = Sets.newHashSetWithExpectedSize(sourceFileExtensions.size() + HEADER_FILE_EXTENSIONS.size());
fileExtensions.addAll(sourceFileExtensions);
// add header files extension explicitly as the model only provides the extensions of source files.
fileExtensions.addAll(HEADER_FILE_EXTENSIONS);
PsiManager psiManager = PsiManager.getInstance(project);
List<AbstractTreeNode> children = Lists.newArrayList();
for (RootDirectory rootDirectory : rootDirectories.values()) {
PsiDirectory psiDir = psiManager.findDirectory(rootDirectory.rootDir);
if (psiDir != null) {
children.add(new NativeAndroidSourceDirectoryNode(project, psiDir, settings, fileExtensions, rootDirectory.sourceFolders, rootDirectory.sourceFiles));
}
}
return children;
}
Aggregations