2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.lang.java;
19 import com.intellij.codeInsight.CodeInsightBundle;
20 import com.intellij.codeInsight.editorActions.CodeDocumentationUtil;
21 import com.intellij.codeInsight.javadoc.JavaDocExternalFilter;
22 import com.intellij.codeInsight.javadoc.JavaDocInfoGenerator;
23 import com.intellij.codeInsight.javadoc.JavaDocUtil;
24 import com.intellij.lang.CodeDocumentationAwareCommenter;
25 import com.intellij.lang.LangBundle;
26 import com.intellij.lang.LanguageCommenters;
27 import com.intellij.lang.documentation.CodeDocumentationProvider;
28 import com.intellij.lang.documentation.ExternalDocumentationProvider;
29 import com.intellij.openapi.diagnostic.Logger;
30 import com.intellij.openapi.module.Module;
31 import com.intellij.openapi.module.ModuleUtil;
32 import com.intellij.openapi.project.IndexNotReadyException;
33 import com.intellij.openapi.project.Project;
34 import com.intellij.openapi.roots.*;
35 import com.intellij.openapi.util.io.FileUtil;
36 import com.intellij.openapi.vfs.JarFileSystem;
37 import com.intellij.openapi.vfs.VirtualFile;
38 import com.intellij.openapi.vfs.VirtualFileManager;
39 import com.intellij.openapi.vfs.VirtualFileSystem;
40 import com.intellij.openapi.vfs.ex.http.HttpFileSystem;
41 import com.intellij.psi.*;
42 import com.intellij.psi.impl.beanProperties.BeanPropertyElement;
43 import com.intellij.psi.impl.source.javadoc.PsiDocParamRef;
44 import com.intellij.psi.infos.CandidateInfo;
45 import com.intellij.psi.javadoc.PsiDocComment;
46 import com.intellij.psi.javadoc.PsiDocTag;
47 import com.intellij.psi.util.PsiFormatUtil;
48 import com.intellij.util.StringBuilderSpinAllocator;
49 import com.intellij.util.containers.HashMap;
50 import org.jetbrains.annotations.NonNls;
51 import org.jetbrains.annotations.Nullable;
53 import java.util.ArrayList;
54 import java.util.List;
58 * @author Maxim.Mossienko
60 public class JavaDocumentationProvider implements CodeDocumentationProvider, ExternalDocumentationProvider {
61 private static final Logger LOG = Logger.getInstance("#" + JavaDocumentationProvider.class.getName());
62 private static final String LINE_SEPARATOR = "\n";
64 @NonNls private static final String PARAM_TAG = "@param";
65 @NonNls private static final String RETURN_TAG = "@return";
66 @NonNls private static final String THROWS_TAG = "@throws";
67 @NonNls public static final String HTML_EXTENSION = ".html";
68 @NonNls public static final String PACKAGE_SUMMARY_FILE = "package-summary.html";
70 public String getQuickNavigateInfo(PsiElement element) {
71 if (element instanceof PsiClass) {
72 return generateClassInfo((PsiClass)element);
74 else if (element instanceof PsiMethod) {
75 return generateMethodInfo((PsiMethod)element);
77 else if (element instanceof PsiField) {
78 return generateFieldInfo((PsiField)element);
80 else if (element instanceof PsiVariable) {
81 return generateVariableInfo((PsiVariable)element);
83 else if (element instanceof PsiPackage) {
84 return generatePackageInfo((PsiPackage)element);
86 else if (element instanceof BeanPropertyElement) {
87 return generateMethodInfo(((BeanPropertyElement) element).getMethod());
92 public List<String> getUrlFor(final PsiElement element, final PsiElement originalElement) {
93 return getExternalJavaDocUrl(element);
96 private static void newLine(StringBuffer buffer) {
97 // Don't know why space has to be added after newline for good text alignment...
101 private static void generateType(@NonNls StringBuffer buffer, PsiType type, PsiElement context) {
102 if (type instanceof PsiPrimitiveType) {
103 buffer.append(type.getCanonicalText());
108 if (type instanceof PsiWildcardType) {
109 PsiWildcardType wc = ((PsiWildcardType)type);
110 PsiType bound = wc.getBound();
115 buffer.append(wc.isExtends() ? " extends " : " super ");
116 generateType(buffer, bound, context);
120 if (type instanceof PsiArrayType) {
121 generateType(buffer, ((PsiArrayType)type).getComponentType(), context);
122 if (type instanceof PsiEllipsisType) {
123 buffer.append("...");
132 if (type instanceof PsiClassType) {
133 PsiClassType.ClassResolveResult result = ((PsiClassType)type).resolveGenerics();
134 PsiClass psiClass = result.getElement();
135 PsiSubstitutor psiSubst = result.getSubstitutor();
137 if (psiClass == null || psiClass instanceof PsiTypeParameter) {
138 buffer.append(type.getPresentableText());
142 buffer.append(JavaDocUtil.getShortestClassName(psiClass, context));
144 if (psiClass.hasTypeParameters()) {
145 StringBuffer subst = new StringBuffer();
146 boolean goodSubst = true;
148 PsiTypeParameter[] params = psiClass.getTypeParameters();
151 for (int i = 0; i < params.length; i++) {
152 PsiType t = psiSubst.substitute(params[i]);
159 generateType(subst, t, context);
161 if (i < params.length - 1) {
168 String text = subst.toString();
176 private static void generateInitializer(StringBuffer buffer, PsiVariable variable) {
177 PsiExpression initializer = variable.getInitializer();
178 if (initializer != null) {
179 String text = initializer.getText().trim();
180 int index1 = text.indexOf('\n');
181 if (index1 < 0) index1 = text.length();
182 int index2 = text.indexOf('\r');
183 if (index2 < 0) index2 = text.length();
184 int index = Math.min(index1, index2);
185 boolean trunc = index < text.length();
186 text = text.substring(0, index);
187 buffer.append(" = ");
190 buffer.append("...");
195 private static void generateModifiers(StringBuffer buffer, PsiElement element) {
196 String modifiers = PsiFormatUtil.formatModifiers(element, PsiFormatUtil.JAVADOC_MODIFIERS_ONLY);
198 if (modifiers.length() > 0) {
199 buffer.append(modifiers);
204 private static String generatePackageInfo(PsiPackage aPackage) {
205 return aPackage.getQualifiedName();
208 @SuppressWarnings({"HardCodedStringLiteral"})
209 private static String generateClassInfo(PsiClass aClass) {
210 StringBuffer buffer = new StringBuffer();
212 if (aClass instanceof PsiAnonymousClass) return LangBundle.message("java.terms.anonymous.class");
214 PsiFile file = aClass.getContainingFile();
215 final Module module = ModuleUtil.findModuleForPsiElement(file);
216 if (module != null) {
217 buffer.append('[').append(module.getName()).append("] ");
220 if (file instanceof PsiJavaFile) {
221 String packageName = ((PsiJavaFile)file).getPackageName();
222 if (packageName.length() > 0) {
223 buffer.append(packageName);
228 generateModifiers(buffer, aClass);
230 final String classString = aClass.isAnnotationType() ? "java.terms.annotation.interface"
231 : aClass.isInterface()
232 ? "java.terms.interface"
233 : aClass instanceof PsiTypeParameter
234 ? "java.terms.type.parameter"
235 : aClass.isEnum() ? "java.terms.enum" : "java.terms.class";
236 buffer.append(LangBundle.message(classString)).append(" ");
238 buffer.append(JavaDocUtil.getShortestClassName(aClass, aClass));
240 if (aClass.hasTypeParameters()) {
241 PsiTypeParameter[] parms = aClass.getTypeParameters();
245 for (int i = 0; i < parms.length; i++) {
246 PsiTypeParameter p = parms[i];
248 buffer.append(p.getName());
250 PsiClassType[] refs = p.getExtendsList().getReferencedTypes();
252 if (refs.length > 0) {
253 buffer.append(" extends ");
255 for (int j = 0; j < refs.length; j++) {
256 generateType(buffer, refs[j], aClass);
258 if (j < refs.length - 1) {
259 buffer.append(" & ");
264 if (i < parms.length - 1) {
273 if (!aClass.isEnum() && !aClass.isAnnotationType()) {
274 PsiReferenceList extendsList = aClass.getExtendsList();
275 refs = extendsList == null ? PsiClassType.EMPTY_ARRAY : extendsList.getReferencedTypes();
276 if (refs.length > 0 || !aClass.isInterface() && !"java.lang.Object".equals(aClass.getQualifiedName())) {
277 buffer.append(" extends ");
278 if (refs.length == 0) {
279 buffer.append("Object");
282 for (int i = 0; i < refs.length; i++) {
283 generateType(buffer, refs[i], aClass);
285 if (i < refs.length - 1) {
293 refs = aClass.getImplementsListTypes();
294 if (refs.length > 0) {
296 buffer.append("implements ");
297 for (int i = 0; i < refs.length; i++) {
298 generateType(buffer, refs[i], aClass);
300 if (i < refs.length - 1) {
306 return buffer.toString();
309 @SuppressWarnings({"HardCodedStringLiteral"})
310 public static String generateMethodInfo(PsiMethod method) {
311 StringBuffer buffer = new StringBuffer();
313 PsiClass parentClass = method.getContainingClass();
315 if (parentClass != null) {
316 buffer.append(JavaDocUtil.getShortestClassName(parentClass, method));
320 generateModifiers(buffer, method);
322 PsiTypeParameter[] params = method.getTypeParameters();
324 if (params.length > 0) {
326 for (int i = 0; i < params.length; i++) {
327 PsiTypeParameter param = params[i];
329 buffer.append(param.getName());
331 PsiClassType[] extendees = param.getExtendsList().getReferencedTypes();
333 if (extendees.length > 0) {
334 buffer.append(" extends ");
336 for (int j = 0; j < extendees.length; j++) {
337 generateType(buffer, extendees[j], method);
339 if (j < extendees.length - 1) {
340 buffer.append(" & ");
345 if (i < params.length - 1) {
352 if (method.getReturnType() != null) {
353 generateType(buffer, method.getReturnType(), method);
357 buffer.append(method.getName());
360 PsiParameter[] parms = method.getParameterList().getParameters();
361 for (int i = 0; i < parms.length; i++) {
362 PsiParameter parm = parms[i];
363 generateType(buffer, parm.getType(), method);
365 if (parm.getName() != null) {
366 buffer.append(parm.getName());
368 if (i < parms.length - 1) {
375 PsiClassType[] refs = method.getThrowsList().getReferencedTypes();
376 if (refs.length > 0) {
378 buffer.append(" throws ");
379 for (int i = 0; i < refs.length; i++) {
380 PsiClass throwsClass = refs[i].resolve();
382 if (throwsClass != null) {
383 buffer.append(JavaDocUtil.getShortestClassName(throwsClass, method));
386 buffer.append(refs[i].getPresentableText());
389 if (i < refs.length - 1) {
395 return buffer.toString();
398 private static String generateFieldInfo(PsiField field) {
399 StringBuffer buffer = new StringBuffer();
400 PsiClass parentClass = field.getContainingClass();
402 if (parentClass != null) {
403 buffer.append(JavaDocUtil.getShortestClassName(parentClass, field));
407 generateModifiers(buffer, field);
409 generateType(buffer, field.getType(), field);
411 buffer.append(field.getName());
413 generateInitializer(buffer, field);
415 return buffer.toString();
418 private static String generateVariableInfo(PsiVariable variable) {
419 StringBuffer buffer = new StringBuffer();
421 generateModifiers(buffer, variable);
423 generateType(buffer, variable.getType(), variable);
427 buffer.append(variable.getName());
428 generateInitializer(buffer, variable);
430 return buffer.toString();
433 public PsiComment findExistingDocComment(final PsiComment _element) {
434 PsiElement parentElement = _element.getParent();
436 return parentElement instanceof PsiDocCommentOwner ? ((PsiDocCommentOwner)parentElement).getDocComment() : null;
439 public String generateDocumentationContentStub(PsiComment _element) {
440 PsiElement parentElement = _element.getParent();
441 final Project project = _element.getProject();
442 final StringBuilder builder = StringBuilderSpinAllocator.alloc();
444 if (parentElement instanceof PsiMethod) {
445 PsiMethod psiMethod = (PsiMethod)parentElement;
446 final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
447 final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter)LanguageCommenters.INSTANCE
448 .forLanguage(parentElement.getLanguage());
449 final Map<String, String> param2Description = new HashMap<String, String>();
450 final PsiMethod[] superMethods = psiMethod.findSuperMethods();
451 for (PsiMethod superMethod : superMethods) {
452 final PsiDocComment comment = superMethod.getDocComment();
453 if (comment != null) {
454 final PsiDocTag[] params = comment.findTagsByName("param");
455 for (PsiDocTag param : params) {
456 final PsiElement[] dataElements = param.getDataElements();
457 if (dataElements != null) {
458 String paramName = null;
459 for (PsiElement dataElement : dataElements) {
460 if (dataElement instanceof PsiDocParamRef) {
461 paramName = dataElement.getReference().getCanonicalText();
465 if (paramName != null) {
466 param2Description.put(paramName, param.getText());
472 for (PsiParameter parameter : parameters) {
473 String description = param2Description.get(parameter.getName());
474 if (description != null) {
475 builder.append(CodeDocumentationUtil.createDocCommentLine("", project, commenter));
476 if (description.indexOf('\n') > -1) description = description.substring(0, description.lastIndexOf('\n'));
477 builder.append(description);
480 builder.append(CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter));
481 builder.append(parameter.getName());
483 builder.append(LINE_SEPARATOR);
486 final PsiTypeParameterList typeParameterList = psiMethod.getTypeParameterList();
487 if (typeParameterList != null) {
488 createTypeParamsListComment(builder, project, commenter, typeParameterList);
490 if (psiMethod.getReturnType() != null && psiMethod.getReturnType() != PsiType.VOID) {
491 builder.append(CodeDocumentationUtil.createDocCommentLine(RETURN_TAG, project, commenter));
492 builder.append(LINE_SEPARATOR);
495 final PsiJavaCodeReferenceElement[] references = psiMethod.getThrowsList().getReferenceElements();
496 for (PsiJavaCodeReferenceElement reference : references) {
497 builder.append(CodeDocumentationUtil.createDocCommentLine(THROWS_TAG, project, commenter));
498 builder.append(reference.getText());
499 builder.append(LINE_SEPARATOR);
502 else if (parentElement instanceof PsiClass) {
503 final PsiTypeParameterList typeParameterList = ((PsiClass)parentElement).getTypeParameterList();
504 if (typeParameterList != null) {
505 final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter)LanguageCommenters.INSTANCE
506 .forLanguage(parentElement.getLanguage());
507 createTypeParamsListComment(builder, project, commenter, typeParameterList);
510 return builder.length() > 0 ? builder.toString() : null;
513 StringBuilderSpinAllocator.dispose(builder);
517 private static void createTypeParamsListComment(final StringBuilder buffer,
518 final Project project,
519 final CodeDocumentationAwareCommenter commenter,
520 final PsiTypeParameterList typeParameterList) {
521 final PsiTypeParameter[] typeParameters = typeParameterList.getTypeParameters();
522 for (PsiTypeParameter typeParameter : typeParameters) {
523 buffer.append(CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter));
524 buffer.append("<").append(typeParameter.getName()).append(">");
525 buffer.append(LINE_SEPARATOR);
529 public String generateDoc(final PsiElement element, final PsiElement originalElement) {
530 if (element instanceof PsiMethodCallExpression) {
531 return getMethodCandidateInfo((PsiMethodCallExpression)element);
535 //external documentation finder
536 return generateExternalJavadoc(element);
539 public PsiElement getDocumentationElementForLookupItem(final PsiManager psiManager, final Object object, final PsiElement element) {
544 public static String generateExternalJavadoc(final PsiElement element) {
545 final JavaDocInfoGenerator javaDocInfoGenerator = new JavaDocInfoGenerator(element.getProject(), element);
546 final List<String> docURLs = getExternalJavaDocUrl(element);
547 return JavaDocExternalFilter.filterInternalDocInfo(javaDocInfoGenerator.generateDocInfo(docURLs));
552 private static String generateExternalJavadoc(final PsiElement element, String fromUrl, boolean checkCompiled, JavaDocExternalFilter filter) {
553 if (!checkCompiled || element instanceof PsiCompiledElement) {
555 String externalDoc = filter.getExternalDocInfoForElement(fromUrl, element);
556 if (externalDoc != null && externalDoc.length() > 0) {
560 catch (Exception e) {
561 //try to generate some javadoc
567 private String getMethodCandidateInfo(PsiMethodCallExpression expr) {
568 final PsiResolveHelper rh = JavaPsiFacade.getInstance(expr.getProject()).getResolveHelper();
569 final CandidateInfo[] candidates = rh.getReferencedMethodCandidates(expr, true);
570 final String text = expr.getText();
571 if (candidates.length > 0) {
572 @NonNls final StringBuffer sb = new StringBuffer();
574 for (final CandidateInfo candidate : candidates) {
575 final PsiElement element = candidate.getElement();
577 if (!(element instanceof PsiMethod)) {
581 final String str = PsiFormatUtil.formatMethod((PsiMethod)element, candidate.getSubstitutor(),
582 PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_PARAMETERS,
583 PsiFormatUtil.SHOW_TYPE);
584 createElementLink(sb, element, str);
587 return CodeInsightBundle.message("javadoc.candiates", text, sb);
590 return CodeInsightBundle.message("javadoc.candidates.not.found", text);
593 private static void createElementLink(@NonNls final StringBuffer sb, final PsiElement element, final String str) {
594 sb.append(" <a href=\"psi_element://");
595 sb.append(JavaDocUtil.getReferenceText(element.getProject(), element));
603 public static List<String> getExternalJavaDocUrl(final PsiElement element) {
604 List<String> urls = null;
606 if (element instanceof PsiClass) {
607 urls = findUrlForClass((PsiClass)element);
609 else if (element instanceof PsiField) {
610 PsiField field = (PsiField)element;
611 PsiClass aClass = field.getContainingClass();
612 if (aClass != null) {
613 urls = findUrlForClass(aClass);
615 for (int i = 0; i < urls.size(); i++) {
616 urls.set(i, urls.get(i) + "#" + field.getName());
621 else if (element instanceof PsiMethod) {
622 PsiMethod method = (PsiMethod)element;
623 PsiClass aClass = method.getContainingClass();
624 if (aClass != null) {
625 final List<String> classUrls = findUrlForClass(aClass);
627 if (classUrls != null) {
628 urls = new ArrayList<String>();
629 String signature = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY,
630 PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS | PsiFormatUtil.SHOW_RAW_TYPE,
631 PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_FQ_CLASS_NAMES | PsiFormatUtil.SHOW_RAW_TYPE, 999);
632 for (String classUrl : classUrls) {
633 urls.add(classUrl + "#" + signature);
635 signature = PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY,
636 PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS,
637 PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_FQ_CLASS_NAMES, 999);
638 for (String classUrl : classUrls) {
639 urls.add(classUrl + "#" + signature);
644 else if (element instanceof PsiPackage) {
645 urls = findUrlForPackage((PsiPackage)element);
647 else if (element instanceof PsiDirectory) {
648 PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(((PsiDirectory)element));
649 if (aPackage != null) {
650 urls = findUrlForPackage(aPackage);
658 for (int i = 0; i < urls.size(); i++) {
659 urls.set(i, FileUtil.toSystemIndependentName(urls.get(i)));
666 public static List<String> findUrlForClass(PsiClass aClass) {
667 String qName = aClass.getQualifiedName();
668 if (qName == null) return null;
669 PsiFile file = aClass.getContainingFile();
670 if (!(file instanceof PsiJavaFile)) return null;
671 String packageName = ((PsiJavaFile)file).getPackageName();
674 if (packageName.length() > 0) {
675 relPath = packageName.replace('.', '/') + '/' + qName.substring(packageName.length() + 1) + HTML_EXTENSION;
678 relPath = qName + HTML_EXTENSION;
681 final PsiFile containingFile = aClass.getContainingFile();
682 if (containingFile == null) return null;
683 final VirtualFile virtualFile = containingFile.getVirtualFile();
684 if (virtualFile == null) return null;
686 return findUrlForVirtualFile(containingFile.getProject(), virtualFile, relPath);
690 public static List<String> findUrlForVirtualFile(final Project project, final VirtualFile virtualFile, final String relPath) {
691 final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
692 Module module = fileIndex.getModuleForFile(virtualFile);
693 if (module == null) {
694 final VirtualFileSystem fs = virtualFile.getFileSystem();
695 if (fs instanceof JarFileSystem) {
696 final VirtualFile jar = ((JarFileSystem)fs).getVirtualFileForJar(virtualFile);
698 module = fileIndex.getModuleForFile(jar);
702 if (module != null) {
703 String[] javadocPaths = ModuleRootManager.getInstance(module).getRootUrls(JavadocOrderRootType.getInstance());
704 List<String> httpRoot = getHttpRoots(javadocPaths, relPath);
705 if (httpRoot != null) return httpRoot;
708 final List<OrderEntry> orderEntries = fileIndex.getOrderEntriesForFile(virtualFile);
709 for (OrderEntry orderEntry : orderEntries) {
710 final String[] files = orderEntry.getUrls(JavadocOrderRootType.getInstance());
711 final List<String> httpRoot = getHttpRoots(files, relPath);
712 if (httpRoot != null) return httpRoot;
718 public static List<String> getHttpRoots(final String[] roots, String relPath) {
719 final ArrayList<String> result = new ArrayList<String>();
720 for (String root : roots) {
721 final VirtualFile virtualFile = VirtualFileManager.getInstance().findFileByUrl(root);
722 if (virtualFile != null) {
723 if (virtualFile.getFileSystem() instanceof HttpFileSystem) {
724 String url = virtualFile.getUrl();
725 if (!url.endsWith("/")) url += "/";
726 result.add(url + relPath);
729 VirtualFile file = virtualFile.findFileByRelativePath(relPath);
730 if (file != null) result.add(file.getUrl());
735 return result.isEmpty() ? null : result;
739 public static List<String> findUrlForPackage(PsiPackage aPackage) {
740 String qName = aPackage.getQualifiedName();
741 qName = qName.replace('.', '/') + '/' + PACKAGE_SUMMARY_FILE;
742 for (PsiDirectory directory : aPackage.getDirectories()) {
743 List<String> url = findUrlForVirtualFile(aPackage.getProject(), directory.getVirtualFile(), qName);
751 public PsiElement getDocumentationElementForLink(final PsiManager psiManager, final String link, final PsiElement context) {
752 return JavaDocUtil.findReferenceTarget(psiManager, link, context);
755 public String fetchExternalDocumentation(final Project project, PsiElement element, final List<String> docUrls) {
756 return fetchExternalJavadoc(element, project, docUrls);
759 public static String fetchExternalJavadoc(PsiElement element, final Project project, final List<String> docURLs) {
760 final JavaDocExternalFilter docFilter = new JavaDocExternalFilter(project);
762 if (docURLs != null) {
763 for (String docURL : docURLs) {
765 final String javadoc = generateExternalJavadoc(element, docURL, true, docFilter);
766 if (javadoc != null) return javadoc;
768 catch (IndexNotReadyException e) {
771 catch (Exception e) {
772 LOG.info(e); //connection problems should be ignored