diff --git a/platform/util/src/com/intellij/util/io/IntToIntBtree.java b/platform/util/src/com/intellij/util/io/IntToIntBtree.java
index bf9519a7c9ec..f918cf1e532b 100644
--- a/platform/util/src/com/intellij/util/io/IntToIntBtree.java
+++ b/platform/util/src/com/intellij/util/io/IntToIntBtree.java
@@ -17,11 +17,13 @@ abstract class IntToIntBtree {
final BtreeIndexNodeView root;
private int maxStepsSearched;
private int pagesCount;
- private int size;
+ private int count;
+ private int movedMembersCount;
private final byte[] buffer;
private boolean isLarge = true;
private final ISimpleStorage storage;
+ private boolean offloadToSiblingsBeforeSplit = false; // TODO till effective insertion to page
public IntToIntBtree(int _pageSize, int rootAddress, ISimpleStorage _storage, boolean initial) {
pageSize = _pageSize;
@@ -66,7 +68,7 @@ abstract class IntToIntBtree {
int index = currentIndexNode.locate(key, true);
if (index < 0) {
- ++size;
+ ++count;
currentIndexNode.insert(key, value, -index - 1);
} else {
currentIndexNode.setAddressAt(index, value);
@@ -101,6 +103,18 @@ abstract class IntToIntBtree {
this.pagesCount = pagesCount;
}
+ public int getMovedMembersCount() {
+ return movedMembersCount;
+ }
+
+ public void setMovedMembersCount(int movedMembersCount) {
+ this.movedMembersCount = movedMembersCount;
+ }
+
+ void dumpStatistics() {
+ IOStatistics.dump("pagecount:" + pagesCount + ", height:" + maxStepsSearched + ", movedMembers:"+movedMembersCount);
+ }
+
void doFlush() {
//pagesCache.clear();
}
@@ -212,6 +226,7 @@ abstract class IntToIntBtree {
static class BtreeIndexNodeView extends BtreePage {
private boolean isIndexLeaf;
private boolean isIndexLeafSet;
+ private static final int LARGE_MOVE_THRESHOLD = 5;
BtreeIndexNodeView(IntToIntBtree btree) {
super(btree);
@@ -325,63 +340,8 @@ abstract class IntToIntBtree {
if (parentAddress != 0) {
parent = new BtreeIndexNodeView(btree);
parent.setAddress(parentAddress);
- int indexInParent = isIndexLeaf() ? parent.search(keyAt(0)) : -1;
- BtreeIndexNodeView sibling = new BtreeIndexNodeView(btree);
-
- if (indexInParent > 0) {
- if (doSanityCheck) {
- myAssert(parent.keyAt(indexInParent) == keyAt(0));
- myAssert(parent.addressAt(indexInParent + 1) == -address);
- }
-
- int siblingAddress = parent.addressAt(indexInParent);
- sibling.setAddress(-siblingAddress);
-
- if (!sibling.isFull() && sibling.getChildrenCount() + 1 != sibling.getMaxChildrenCount()) {
- if (doSanityCheck) {
- sibling.dump("Offloading to left sibling");
- parent.dump("parent before");
- }
-
- sibling.insert(keyAt(0), addressAt(0), sibling.getChildrenCount());
- if (doSanityCheck) {
- sibling.dump("Left sibling after");
- }
-
- parent.setKeyAt(indexInParent, keyAt(1));
-
- int indexOflastChildToMove = getChildrenCount() - 1;
- if (btree.isLarge) {
- final int bytesToMove = indexOflastChildToMove * INTERIOR_SIZE;
- getBytes(indexToOffset(1), btree.buffer, 0, bytesToMove);
- putBytes(indexToOffset(0), btree.buffer, 0, bytesToMove);
- } else {
- for(int i = 0; i < indexOflastChildToMove; ++i) {
- setAddressAt(i, addressAt(i + 1));
- setKeyAt(i, keyAt(i + 1));
- }
- }
-
- setChildrenCount((short)indexOflastChildToMove);
- } else if (indexInParent + 1 < parent.getChildrenCount()) {
- insertToRightSibling(parent, indexInParent + 1, sibling);
- }
- // TODO: move members in non leaf level + handle cases below
- } /*else if (indexInParent == -1) {
- insertToRightSibling(parent, 0, sibling);
- } else {
- int a = 1;
- }*/
-
- if (!isFull()) {
- sync();
- parent.sync();
-
- if (doSanityCheck) {
- dump("old node after split:");
- parent.dump("Parent node after split");
- }
- return parentAddress;
+ if (btree.offloadToSiblingsBeforeSplit) {
+ if (doOffloadToSiblings(parent)) return parentAddress;
}
}
@@ -448,7 +408,7 @@ abstract class IntToIntBtree {
}
int newRootAddress = btree.nextPage();
if (doSanityCheck) {
- System.out.println("Pages:"+btree.pagesCount+", elements:"+btree.size + ", average:" + (btree.maxStepsSearched + 1));
+ System.out.println("Pages:"+btree.pagesCount+", elements:"+btree.count + ", average:" + (btree.maxStepsSearched + 1));
}
btree.setRootAddress(newRootAddress);
parentAddress = newRootAddress;
@@ -472,6 +432,70 @@ abstract class IntToIntBtree {
return parentAddress;
}
+ private boolean doOffloadToSiblings(BtreeIndexNodeView parent) {
+ int indexInParent = isIndexLeaf() ? parent.search(keyAt(0)) : -1;
+ BtreeIndexNodeView sibling = new BtreeIndexNodeView(btree);
+
+ if (indexInParent > 0) {
+ if (doSanityCheck) {
+ myAssert(parent.keyAt(indexInParent) == keyAt(0));
+ myAssert(parent.addressAt(indexInParent + 1) == -address);
+ }
+
+ int siblingAddress = parent.addressAt(indexInParent);
+ sibling.setAddress(-siblingAddress);
+
+ if (!sibling.isFull() && sibling.getChildrenCount() + 1 != sibling.getMaxChildrenCount()) {
+ if (doSanityCheck) {
+ sibling.dump("Offloading to left sibling");
+ parent.dump("parent before");
+ }
+
+ sibling.insert(keyAt(0), addressAt(0), sibling.getChildrenCount());
+ if (doSanityCheck) {
+ sibling.dump("Left sibling after");
+ }
+
+ parent.setKeyAt(indexInParent, keyAt(1));
+
+ int indexOflastChildToMove = getChildrenCount() - 1;
+ if (btree.isLarge) {
+ final int bytesToMove = indexOflastChildToMove * INTERIOR_SIZE;
+ getBytes(indexToOffset(1), btree.buffer, 0, bytesToMove);
+ putBytes(indexToOffset(0), btree.buffer, 0, bytesToMove);
+ }
+ else {
+ for (int i = 0; i < indexOflastChildToMove; ++i) {
+ setAddressAt(i, addressAt(i + 1));
+ setKeyAt(i, keyAt(i + 1));
+ }
+ }
+
+ setChildrenCount((short)indexOflastChildToMove);
+ }
+ else if (indexInParent + 1 < parent.getChildrenCount()) {
+ insertToRightSibling(parent, indexInParent + 1, sibling);
+ }
+ // TODO: move members in non leaf level + handle cases below
+ } /*else if (indexInParent == -1) {
+ insertToRightSibling(parent, 0, sibling);
+ } else {
+ int a = 1;
+ }*/
+
+ if (!isFull()) {
+ sync();
+ parent.sync();
+
+ if (doSanityCheck) {
+ dump("old node after split:");
+ parent.dump("Parent node after split");
+ }
+ return true;
+ }
+ return false;
+ }
+
private void insertToRightSibling(BtreeIndexNodeView parent, int indexInParent, BtreeIndexNodeView sibling) {
int siblingAddress;
siblingAddress = parent.addressAt(indexInParent + 1);
@@ -553,10 +577,13 @@ abstract class IntToIntBtree {
if (doSanityCheck) myAssert(recordCount < getMaxChildrenCount());
setChildrenCount((short)(recordCount + 1));
+ final int itemsToMove = recordCount - index;
+ btree.movedMembersCount += itemsToMove;
+
// TODO Clever books tell us to use Btree for cheaper elements shifting within page
if (isIndexLeaf()) {
- if (btree.isLarge) {
- final int bytesToMove = (recordCount - index) * INTERIOR_SIZE;
+ if (btree.isLarge && itemsToMove > LARGE_MOVE_THRESHOLD) {
+ final int bytesToMove = itemsToMove * INTERIOR_SIZE;
getBytes(indexToOffset(index), btree.buffer, 0, bytesToMove);
putBytes(indexToOffset(index + 1), btree.buffer, 0, bytesToMove);
} else {
@@ -571,7 +598,7 @@ abstract class IntToIntBtree {
//
() {record_count - 1}
//
setAddressAt(recordCount + 1, addressAt(recordCount));
- if (btree.isLarge) {
+ if (btree.isLarge && itemsToMove > LARGE_MOVE_THRESHOLD) {
int elementsAfterIndex = recordCount - index - 1;
if (elementsAfterIndex > 0) {
int bytesToMove = elementsAfterIndex * INTERIOR_SIZE;
diff --git a/platform/util/src/com/intellij/util/io/MappedFileSimpleStorage.java b/platform/util/src/com/intellij/util/io/MappedFileSimpleStorage.java
index bc512c0a0506..79dd723d2be8 100644
--- a/platform/util/src/com/intellij/util/io/MappedFileSimpleStorage.java
+++ b/platform/util/src/com/intellij/util/io/MappedFileSimpleStorage.java
@@ -13,9 +13,9 @@ final class MappedFileSimpleStorage implements ISimpleStorage {
storage = new ResizeableMappedFile(file, initialSize, PersistentEnumeratorBase.ourLock);
}
- public MappedFileSimpleStorage(File file, int initialSize, int pageSize, float growFactor, boolean zeroPagesWhenExpand) throws IOException {
+ public MappedFileSimpleStorage(File file, int initialSize, int pageSize, boolean zeroPagesWhenExpand) throws IOException {
FileUtil.createIfDoesntExist(file);
- storage = new ResizeableMappedFile(file, initialSize, PersistentEnumeratorBase.ourLock, pageSize, growFactor, zeroPagesWhenExpand);
+ storage = new ResizeableMappedFile(file, initialSize, PersistentEnumeratorBase.ourLock, pageSize, zeroPagesWhenExpand);
}
@Override
diff --git a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java
index 18ae5bbdbe11..181434e79560 100644
--- a/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java
+++ b/platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java
@@ -45,7 +45,7 @@ public class PersistentBTreeEnumerator extends PersistentEnumeratorBase dataDescriptor, int initialSize) throws IOException {
- super(file, new MappedFileSimpleStorage(file, initialSize, 1024 * 1024, 10f, false), dataDescriptor, initialSize);
+ super(file, new MappedFileSimpleStorage(file, initialSize, 1024 * 1024, false), dataDescriptor, initialSize);
myInlineKeysNoMapping = myDataDescriptor instanceof InlineKeyDescriptor && !wantInlineKeyMapping();
myBuffer = new byte[getRecordSize()];
@@ -96,6 +96,7 @@ public class PersistentBTreeEnumerator extends PersistentEnumeratorBase extends PersistentEnumeratorBase extends PersistentEnumeratorBase implements Forceable, Closeable {
}
protected final void markDirty(boolean dirty) throws IOException {
- if (dirty && isDirty()) return;
+ //assert Thread.holdsLock(this) || Thread.holdsLock(ourLock); // we hold one lock or another so can access myDirty
+ if (dirty && myDirty) return;
synchronized (ourLock) {
if (myDirty) {
if (!dirty) {
diff --git a/platform/util/src/com/intellij/util/io/ResizeableMappedFile.java b/platform/util/src/com/intellij/util/io/ResizeableMappedFile.java
index 464e0d2e8f48..d4c85172ea91 100644
--- a/platform/util/src/com/intellij/util/io/ResizeableMappedFile.java
+++ b/platform/util/src/com/intellij/util/io/ResizeableMappedFile.java
@@ -29,9 +29,8 @@ public class ResizeableMappedFile implements Forceable {
private long myLogicalSize;
private final PagedFileStorage myStorage;
- private final float myGrowFactor;
- public ResizeableMappedFile(final File file, int initialSize, PagedFileStorage.StorageLock lock, int pageSize, float growFactor, boolean zeroWhenExpand) throws IOException {
+ public ResizeableMappedFile(final File file, int initialSize, PagedFileStorage.StorageLock lock, int pageSize, boolean zeroWhenExpand) throws IOException {
myStorage = new PagedFileStorage(file, lock, pageSize, zeroWhenExpand);
if (!file.exists() || file.length() == 0) {
writeLength(0);
@@ -43,13 +42,10 @@ public class ResizeableMappedFile implements Forceable {
resize(initialSize);
}
}
-
- assert growFactor > 8f:"growFactor / 8 should be > 1";
- myGrowFactor = growFactor;
}
public ResizeableMappedFile(final File file, int initialSize, PagedFileStorage.StorageLock lock) throws IOException {
- this(file, initialSize, lock, PagedFileStorage.DEFAULT_BUFFER_SIZE, 13f, true);
+ this(file, initialSize, lock, PagedFileStorage.DEFAULT_BUFFER_SIZE, true);
}
public long length() {
@@ -78,7 +74,7 @@ public class ResizeableMappedFile implements Forceable {
}
private void expand() {
- final long newSize = Math.min(Integer.MAX_VALUE, ((long)((realSize() + 1) * myGrowFactor)) >> 3);
+ final long newSize = Math.min(Integer.MAX_VALUE, ((realSize() + 1) * 13) >> 3);
resize((int)newSize);
}
diff --git a/plugins/android/android.iml b/plugins/android/android.iml
index 620b7ba080dc..b0125fcb44fc 100644
--- a/plugins/android/android.iml
+++ b/plugins/android/android.iml
@@ -31,20 +31,28 @@
+
+
+
+
-
-
-
+
+
+
+
+
+
+
diff --git a/plugins/android/lib/common.jar b/plugins/android/lib/common.jar
index ed6a975e6fbd..006c6e499694 100644
Binary files a/plugins/android/lib/common.jar and b/plugins/android/lib/common.jar differ
diff --git a/plugins/android/lib/ide_common.jar b/plugins/android/lib/ide_common.jar
new file mode 100644
index 000000000000..ea5e33f2bfd8
Binary files /dev/null and b/plugins/android/lib/ide_common.jar differ
diff --git a/plugins/android/lib/kxml2-2.3.0.jar b/plugins/android/lib/kxml2-2.3.0.jar
new file mode 100644
index 000000000000..647095222a50
Binary files /dev/null and b/plugins/android/lib/kxml2-2.3.0.jar differ
diff --git a/plugins/android/lib/layoutlib_api.jar b/plugins/android/lib/layoutlib_api.jar
new file mode 100644
index 000000000000..4fa52af98744
Binary files /dev/null and b/plugins/android/lib/layoutlib_api.jar differ
diff --git a/plugins/android/lib/ninepatch.jar b/plugins/android/lib/ninepatch.jar
new file mode 100644
index 000000000000..a3ca418b94b7
Binary files /dev/null and b/plugins/android/lib/ninepatch.jar differ
diff --git a/plugins/android/lib/sdklib.jar b/plugins/android/lib/sdklib.jar
index f08303dbdd52..4c9d20a9fa35 100644
Binary files a/plugins/android/lib/sdklib.jar and b/plugins/android/lib/sdklib.jar differ
diff --git a/plugins/android/lib/src/ide_common_src.zip b/plugins/android/lib/src/ide_common_src.zip
new file mode 100644
index 000000000000..1341dc31da8e
Binary files /dev/null and b/plugins/android/lib/src/ide_common_src.zip differ
diff --git a/plugins/android/lib/src/layoutlib_api_src.zip b/plugins/android/lib/src/layoutlib_api_src.zip
new file mode 100644
index 000000000000..c560c1db691b
Binary files /dev/null and b/plugins/android/lib/src/layoutlib_api_src.zip differ
diff --git a/plugins/android/lib/src/ninepatch_src.zip b/plugins/android/lib/src/ninepatch_src.zip
new file mode 100644
index 000000000000..1cd3462ed541
Binary files /dev/null and b/plugins/android/lib/src/ninepatch_src.zip differ
diff --git a/plugins/android/resources/icons/zoomActual.png b/plugins/android/resources/icons/zoomActual.png
new file mode 100644
index 000000000000..7d0d91fa2979
Binary files /dev/null and b/plugins/android/resources/icons/zoomActual.png differ
diff --git a/plugins/android/resources/icons/zoomFit.png b/plugins/android/resources/icons/zoomFit.png
new file mode 100644
index 000000000000..f88a24a999cb
Binary files /dev/null and b/plugins/android/resources/icons/zoomFit.png differ
diff --git a/plugins/android/resources/icons/zoomIn.png b/plugins/android/resources/icons/zoomIn.png
new file mode 100644
index 000000000000..e6a7db50be22
Binary files /dev/null and b/plugins/android/resources/icons/zoomIn.png differ
diff --git a/plugins/android/resources/icons/zoomOut.png b/plugins/android/resources/icons/zoomOut.png
new file mode 100644
index 000000000000..8f1a570d0b7a
Binary files /dev/null and b/plugins/android/resources/icons/zoomOut.png differ
diff --git a/plugins/android/resources/messages/AndroidBundle.properties b/plugins/android/resources/messages/AndroidBundle.properties
index 7bfc8c26727b..186420d752e9 100644
--- a/plugins/android/resources/messages/AndroidBundle.properties
+++ b/plugins/android/resources/messages/AndroidBundle.properties
@@ -247,4 +247,14 @@ android.import.dependencies.import.module.task.title=Import library module {0} f
android.import.dependencies.dialog.title=Import Android dependencies from property files
android.import.dependencies.source.roots.dialog.title=Import source roots
android.import.dependencies.source.roots.dialog.label=Choose source roots to add to your project
+sdk.broken.error=Cannot parse Android SDK. Please reconfigure it in Android facet settings
+android.layout.preview.cannot.load.library.error=Failed to load platform rendering library
+android.layout.preview.cannot.load.resources=Cannot load module resources.
+android.layout.preview.editor.name=Preview
+android.layout.preview.tool.window.title=Preview
+android.layout.preview.default.error.message=Cannot perform rendering
+android.layout.preview.zoom.in.action.text=Zoom In
+android.layout.preview.zoom.out.action.text=Zoom Out
+android.layout.preview.zoom.actual.action.text=Zoom to actual size
+android.layout.preview.zoom.to.fit.action.text=Zoom to Fit
restart.adb.fix.text=Restart ADB service and try again
\ No newline at end of file
diff --git a/plugins/android/src/META-INF/plugin.xml b/plugins/android/src/META-INF/plugin.xml
index 3058a2ff9845..a195e93b613f 100644
--- a/plugins/android/src/META-INF/plugin.xml
+++ b/plugins/android/src/META-INF/plugin.xml
@@ -16,6 +16,10 @@
org.jetbrains.android.AndroidProjectComponent
+
+ org.jetbrains.android.uipreview.AndroidLayoutPreviewToolWindowManager
+
+
+
+
+
+
+
+
+
+
+
+ The "layout-devices" element is the root element of this schema.
+
+ It must contain zero or more "device" elements that each define the configurations
+ available for a given device.
+
+ These definitions are used in the Graphical Layout Editor in the
+ Android Development Tools (ADT) plugin for Eclipse.
+
+
+
+
+
+
+
+
+
+ A device element must contain at most one "default" element
+ followed by one or more "config" elements.
+
+ The "default" element defines all the default parameters
+ inherited by the following "config" elements.
+ Each "config" element can override the default values, if any.
+
+ A "device" element also has a required "name" attribute that
+ represents the user-interface name of this device.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The parametersType define all the parameters that can happen either in a
+ "default" element or in a named "config" element.
+ Each parameter element can appear once at most.
+
+ Parameters here are the same as those used to specify alternate Android
+ resources, as documented by
+ http://d.android.com/guide/topics/resources/resources-i18n.html#AlternateResources
+
+
+
+
+
+
+
+
+
+ Specifies the configuration is for a particular Mobile Country Code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies the configuration is for a particular Mobile Network Code.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies that the configuration is for a particular class of screen.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies that the configuration is for a taller/wider than traditional
+ screen. This is based purely on the aspect ration of the screen: QVGA,
+ HVGA, and VGA are notlong; WQVGA, WVGA, FWVGA are long. Note that long
+ may mean either wide or tall, depending on the current orientation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies that the configuration is for a screen that is tall (port) or
+ wide (land).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies the screen density the configuration is defined for. The medium
+ density of traditional HVGA screens (mdpi) is defined to be approximately
+ 160dpi; low density (ldpi) is 120, and high density (hdpi) is 240. There
+ is thus a 4:3 scaling factor between each density, so a 9x9 bitmap in ldpi
+ would be 12x12 is mdpi and 16x16 in hdpi.
+ The special nodpi density that can be used in resource qualifiers is not
+ a valid keyword here.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies the touch type the configuration is defined for.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ If your configuration uses a soft keyboard, use the keyssoft value.
+ If it doesn't and has a real keyboard, use keysexposed or keyshidden.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies the primary text input method the configuration is designed for.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies whether the primary non-touchscreen navigation control is
+ exposed or hidden.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies the primary non-touchscreen navigation method the configuration
+ is designed for.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies the device screen resolution, in pixels.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies the actual density in X of the device screen.
+
+
+
+
+
+
+
+
+
+
+
+
+ Specifies the actual density in Y of the device screen.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The configType defines the content of a "config" element in a "device" element.
+
+ A "config" element can have all the parameters elements defined by
+ "parameterType". It also has a required "name" attribute that indicates the
+ user-interface name for this configuration.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidSdkNotConfiguredException.java b/plugins/android/src/org/jetbrains/android/util/AndroidSdkNotConfiguredException.java
new file mode 100644
index 000000000000..8d341d851490
--- /dev/null
+++ b/plugins/android/src/org/jetbrains/android/util/AndroidSdkNotConfiguredException.java
@@ -0,0 +1,7 @@
+package org.jetbrains.android.util;
+
+/**
+ * @author Eugene.Kudelevsky
+ */
+public class AndroidSdkNotConfiguredException extends Exception {
+}
diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java b/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java
index 88b142170a1c..999bd76508e0 100644
--- a/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java
+++ b/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java
@@ -838,4 +838,43 @@ public class AndroidUtils {
}
return null;
}
+
+ public static int getIntAttrValue(@NotNull final XmlTag tag, @NotNull final String attrName) {
+ String value = ApplicationManager.getApplication().runReadAction(new Computable() {
+ public String compute() {
+ return tag.getAttributeValue(attrName, SdkConstants.NS_RESOURCES);
+ }
+ });
+ try {
+ return Integer.parseInt(value);
+ }
+ catch (NumberFormatException e) {
+ return -1;
+ }
+ }
+
+ @Nullable
+ public static XmlFile[] findXmlFiles(final Project project, final String... paths) {
+ XmlFile[] xmlFiles = new XmlFile[paths.length];
+ for (int i = 0; i < paths.length; i++) {
+ String path = paths[i];
+ final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path);
+ PsiFile psiFile = file != null ? ApplicationManager.getApplication().runReadAction(new Computable() {
+ @Nullable
+ public PsiFile compute() {
+ return PsiManager.getInstance(project).findFile(file);
+ }
+ }) : null;
+ if (psiFile == null) {
+ LOG.info("File " + path + " is not found");
+ return null;
+ }
+ if (!(psiFile instanceof XmlFile)) {
+ LOG.info("File " + path + " is not an xml psiFile");
+ return null;
+ }
+ xmlFiles[i] = (XmlFile)psiFile;
+ }
+ return xmlFiles;
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcWatchedRootProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcWatchedRootProvider.java
index b72e0276676c..d8e5dd45b76e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcWatchedRootProvider.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcWatchedRootProvider.java
@@ -11,6 +11,7 @@ import com.intellij.openapi.roots.WatchedRootsProvider;
import org.jetbrains.annotations.NotNull;
import java.io.File;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -26,12 +27,16 @@ public class MvcWatchedRootProvider implements WatchedRootsProvider {
@NotNull
public Set getRootsToWatch() {
- final Set result = new HashSet();
+ if (!myProject.isInitialized()) return Collections.emptySet();
+
+ Set result = null;
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
final MvcFramework framework = MvcModuleStructureSynchronizer.getFramework(module);
if (framework == null) continue;
+ if (result == null) result = new HashSet();
+
final File sdkWorkDir = framework.getCommonPluginsDir(module);
if (sdkWorkDir != null) {
result.add(sdkWorkDir.getAbsolutePath());
@@ -43,7 +48,7 @@ public class MvcWatchedRootProvider implements WatchedRootsProvider {
}
}
- return result;
+ return result == null ? Collections.emptySet() : result;
}
}