/* * Copyright 2000-2009 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. */ /** * @author cdr */ package com.intellij.codeInsight.intention.impl.config; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.ide.plugins.cl.PluginClassLoader; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.util.ArrayUtil; import com.intellij.util.ObjectUtil; import com.intellij.util.lang.UrlClassLoader; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public final class IntentionActionMetaData { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.intention.impl.config.IntentionActionMetaData"); @NotNull private final IntentionAction myAction; private final ClassLoader myIntentionLoader; private final String myDescriptionDirectoryName; @NotNull public final String[] myCategory; private TextDescriptor[] myExampleUsagesBefore = null; private TextDescriptor[] myExampleUsagesAfter = null; private TextDescriptor myDescription = null; private URL myDirURL = null; @NonNls private static final String BEFORE_TEMPLATE_PREFIX = "before"; @NonNls private static final String AFTER_TEMPLATE_PREFIX = "after"; @NonNls static final String EXAMPLE_USAGE_URL_SUFFIX = ".template"; @NonNls private static final String DESCRIPTION_FILE_NAME = "description.html"; @NonNls private static final String INTENTION_DESCRIPTION_FOLDER = "intentionDescriptions"; public IntentionActionMetaData(@NotNull IntentionAction action, @Nullable ClassLoader loader, @NotNull String[] category, @NotNull String descriptionDirectoryName) { myAction = action; myIntentionLoader = loader; myCategory = category; myDescriptionDirectoryName = descriptionDirectoryName; } public IntentionActionMetaData(@NotNull final IntentionAction action, @NotNull final String[] category, final TextDescriptor description, final TextDescriptor[] exampleUsagesBefore, final TextDescriptor[] exampleUsagesAfter) { myAction = action; myCategory = category; myExampleUsagesBefore = exampleUsagesBefore; myExampleUsagesAfter = exampleUsagesAfter; myDescription = description; myIntentionLoader = null; myDescriptionDirectoryName = null; } public String toString() { return getFamily(); } @NotNull public TextDescriptor[] getExampleUsagesBefore() { if(myExampleUsagesBefore == null){ try { myExampleUsagesBefore = retrieveURLs(getDirURL(), BEFORE_TEMPLATE_PREFIX, EXAMPLE_USAGE_URL_SUFFIX); } catch (MalformedURLException e) { LOG.error(e); } } return myExampleUsagesBefore; } @NotNull public TextDescriptor[] getExampleUsagesAfter() { if(myExampleUsagesAfter == null){ try { myExampleUsagesAfter = retrieveURLs(getDirURL(), AFTER_TEMPLATE_PREFIX, EXAMPLE_USAGE_URL_SUFFIX); } catch (MalformedURLException e) { LOG.error(e); } } return myExampleUsagesAfter; } @NotNull public TextDescriptor getDescription() { if(myDescription == null){ try { final URL dirURL = getDirURL(); URL descriptionURL = new URL(dirURL.toExternalForm() + "/" + DESCRIPTION_FILE_NAME); myDescription = new ResourceTextDescriptor(descriptionURL); } catch (MalformedURLException e) { LOG.error(e); } } return myDescription; } @NotNull private static TextDescriptor[] retrieveURLs(@NotNull URL descriptionDirectory, @NotNull String prefix, @NotNull String suffix) throws MalformedURLException { List<TextDescriptor> urls = new ArrayList<TextDescriptor>(); final FileType[] fileTypes = FileTypeManager.getInstance().getRegisteredFileTypes(); for (FileType fileType : fileTypes) { final String[] extensions = FileTypeManager.getInstance().getAssociatedExtensions(fileType); for (String extension : extensions) { for (int i = 0; ; i++) { URL url = new URL(descriptionDirectory.toExternalForm() + "/" + prefix + "." + extension + (i == 0 ? "" : Integer.toString(i)) + suffix); try { InputStream inputStream = url.openStream(); inputStream.close(); urls.add(new ResourceTextDescriptor(url)); } catch (IOException ioe) { break; } } } } if (urls.isEmpty()) { String[] children; Exception cause = null; try { URI uri = descriptionDirectory.toURI(); children = uri.isOpaque()? null : ObjectUtil.notNull(new File(uri).list(), ArrayUtil.EMPTY_STRING_ARRAY); } catch (URISyntaxException e) { cause = e; children = null; } catch (IllegalArgumentException e) { cause = e; children = null; } LOG.error("URLs not found for available file types and prefix: '"+prefix+"', suffix: '"+suffix+"';" + " in directory: '"+descriptionDirectory+ "'" + (children == null? "" : "; directory contents: "+ Arrays.asList(children)), cause); return new TextDescriptor[0]; } return urls.toArray(new TextDescriptor[urls.size()]); } @Nullable private static URL getIntentionDescriptionDirURL(ClassLoader aClassLoader, String intentionFolderName) { final URL pageURL = aClassLoader.getResource(INTENTION_DESCRIPTION_FOLDER + "/" + intentionFolderName+"/"+ DESCRIPTION_FILE_NAME); if (LOG.isDebugEnabled()) { LOG.debug("Path:"+"intentionDescriptions/" + intentionFolderName); LOG.debug("URL:"+pageURL); } if (pageURL != null) { try { final String url = pageURL.toExternalForm(); return UrlClassLoader.internProtocol(new URL(url.substring(0, url.lastIndexOf('/')))); } catch (MalformedURLException e) { LOG.error(e); } } return null; } private URL getDirURL() { if (myDirURL == null) { myDirURL = getIntentionDescriptionDirURL(myIntentionLoader, myDescriptionDirectoryName); } if (myDirURL == null) { //plugin compatibility myDirURL = getIntentionDescriptionDirURL(myIntentionLoader, getFamily()); } LOG.assertTrue(myDirURL != null, "Intention Description Dir URL is null: " + getFamily() +"; "+myDescriptionDirectoryName + ", " + myIntentionLoader); return myDirURL; } @Nullable public PluginId getPluginId() { if (myIntentionLoader instanceof PluginClassLoader) { return ((PluginClassLoader)myIntentionLoader).getPluginId(); } return null; } @NotNull public String getFamily() { return myAction.getFamilyName(); } @NotNull public IntentionAction getAction() { return myAction; } }