SerializerNotFoundException: better stub problem handling

This commit is contained in:
Dmitry Avdeev
2012-09-03 11:09:29 +04:00
parent 446b4da83f
commit f6045d29d0
7 changed files with 87 additions and 33 deletions
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.stubs;
/**
* @author Dmitry Avdeev
* Date: 8/31/12
*/
public class SerializerNotFoundException extends Exception {
public SerializerNotFoundException(String message) {
super(message);
}
}
@@ -155,7 +155,7 @@ public class StubSerializationHelper {
private final RecentStringInterner myStringInterner = new RecentStringInterner(8192);
public Stub deserialize(InputStream stream) throws IOException {
public Stub deserialize(InputStream stream) throws IOException, SerializerNotFoundException {
FileLocalStringEnumerator storage = new FileLocalStringEnumerator();
StubInputStream inputStream = new StubInputStream(stream, storage);
final int size = DataInputOutputUtil.readINT(inputStream);
@@ -171,11 +171,11 @@ public class StubSerializationHelper {
return deserialize(inputStream, null);
}
private Stub deserialize(StubInputStream stream, Stub parentStub) throws IOException {
private Stub deserialize(StubInputStream stream, @Nullable Stub parentStub) throws IOException, SerializerNotFoundException {
final int id = DataInputOutputUtil.readINT(stream);
final ObjectStubSerializer serializer = getClassById(id);
if (serializer == null) {
LOG.error("No serializer registered for stub: ID=" + id + "; parent stub class=" + (parentStub != null? parentStub.getClass().getName() : "null"));
throw new SerializerNotFoundException("No serializer registered for stub: ID=" + id + "; parent stub class=" + (parentStub != null? parentStub.getClass().getName() : "null"));
}
Stub stub = serializer.deserialize(stream, parentStub);
@@ -29,7 +29,7 @@ public abstract class SerializationManagerEx extends SerializationManager {
public abstract void serialize(Stub rootStub, OutputStream stream);
public abstract Stub deserialize(InputStream stream);
public abstract Stub deserialize(InputStream stream) throws SerializerNotFoundException;
public abstract boolean isNameStorageCorrupted();
@@ -158,7 +158,7 @@ public class SerializationManagerImpl extends SerializationManagerEx implements
}
@Override
public Stub deserialize(InputStream stream) {
public Stub deserialize(InputStream stream) throws SerializerNotFoundException {
initSerializers();
try {
@@ -48,7 +48,7 @@ public class SerializedStubTree {
}
// willIndexStub is one time optimization hint, once can safely pass false
public Stub getStub(boolean willIndexStub) {
public Stub getStub(boolean willIndexStub) throws SerializerNotFoundException {
Stub stubElement = myStubElement;
if (stubElement != null) {
// not null myStubElement means we just built SerializedStubTree for indexing,
@@ -88,32 +88,46 @@ public class StubTreeLoaderImpl extends StubTreeLoader {
}
final int id = Math.abs(FileBasedIndex.getFileId(vFile));
if (id > 0) {
final List<SerializedStubTree> datas = FileBasedIndex.getInstance().getValues(StubUpdatingIndex.INDEX_ID, id, GlobalSearchScope
.fileScope(project, vFile));
final int size = datas.size();
if (size == 1) {
Stub stub = datas.get(0).getStub(false);
return stub instanceof PsiFileStub ? new StubTree((PsiFileStub)stub) : new ObjectStubTree((ObjectStubBase)stub, true);
}
else if (size != 0) {
LOG.error("Twin stubs: " + vFile.getPresentableUrl() + " has " + size + " stub versions. Should only have one. id=" + id);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
final Document doc = FileDocumentManager.getInstance().getCachedDocument(vFile);
if (doc != null) {
FileDocumentManager.getInstance().saveDocument(doc);
}
}
}, ModalityState.NON_MODAL);
FileBasedIndex.getInstance().requestReindex(vFile);
}
if (id <= 0) {
return null;
}
final List<SerializedStubTree> datas = FileBasedIndex.getInstance().getValues(StubUpdatingIndex.INDEX_ID, id, GlobalSearchScope
.fileScope(project, vFile));
final int size = datas.size();
if (size == 1) {
Stub stub;
try {
stub = datas.get(0).getStub(false);
}
catch (SerializerNotFoundException e) {
return processError(vFile, "No stub serializer: " + vFile.getPresentableUrl() + ": " + e.getMessage(), e);
}
return stub instanceof PsiFileStub ? new StubTree((PsiFileStub)stub) : new ObjectStubTree((ObjectStubBase)stub, true);
}
else if (size != 0) {
return processError(vFile, "Twin stubs: " + vFile.getPresentableUrl() + " has " + size + " stub versions. Should only have one. id=" + id,
null);
}
return null;
}
private static ObjectStubTree processError(final VirtualFile vFile, String message, @Nullable Exception e) {
LOG.error(message, e);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
final Document doc = FileDocumentManager.getInstance().getCachedDocument(vFile);
if (doc != null) {
FileDocumentManager.getInstance().saveDocument(doc);
}
}
}, ModalityState.NON_MODAL);
FileBasedIndex.getInstance().requestReindex(vFile);
return null;
}
@@ -254,7 +254,13 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
throws StorageException {
checkNameStorage();
final Map<StubIndexKey, Map<Object, StubIdList>> newStubTree = getStubTree(newData);
final Map<StubIndexKey, Map<Object, StubIdList>> newStubTree;
try {
newStubTree = getStubTree(newData);
}
catch (SerializerNotFoundException e) {
throw new StorageException(e);
}
final StubIndexImpl stubIndex = getStubIndex();
final Collection<StubIndexKey> allStubIndices = stubIndex.getAllStubIndexKeys();
@@ -268,7 +274,13 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
getWriteLock().lock();
final Map<Integer, SerializedStubTree> oldData = readOldData(inputId);
final Map<StubIndexKey, Map<Object, StubIdList>> oldStubTree = getStubTree(oldData);
final Map<StubIndexKey, Map<Object, StubIdList>> oldStubTree;
try {
oldStubTree = getStubTree(oldData);
}
catch (SerializerNotFoundException e) {
throw new StorageException(e);
}
super.updateWithMap(inputId, newData, oldKeysGetter);
@@ -302,7 +314,8 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi
}
}
private static Map<StubIndexKey, Map<Object, StubIdList>> getStubTree(@NotNull final Map<Integer, SerializedStubTree> data) {
private static Map<StubIndexKey, Map<Object, StubIdList>> getStubTree(@NotNull final Map<Integer, SerializedStubTree> data)
throws SerializerNotFoundException {
final Map<StubIndexKey, Map<Object, StubIdList>> stubTree;
if (!data.isEmpty()) {
final SerializedStubTree stub = data.values().iterator().next();