Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a case sensitive variant of IContentType.isAssociatedWith #673 #1235

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.core.contenttype; singleton:=true
Bundle-Version: 3.9.300.qualifier
Bundle-Version: 3.10.0.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Require-Bundle: org.eclipse.equinox.preferences;bundle-version="[3.2.0,4.0.0)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,26 @@
*******************************************************************************/
package org.eclipse.core.internal.content;

import java.io.*;
import java.util.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.internal.runtime.RuntimeLog;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.content.*;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.InvalidRegistryObjectException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentDescriber;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeSettings;
import org.eclipse.core.runtime.content.ITextContentDescriber;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.osgi.util.NLS;
import org.osgi.service.prefs.BackingStoreException;
Expand Down Expand Up @@ -377,15 +392,15 @@ boolean hasBuiltInAssociations() {
return builtInAssociations;
}

boolean hasFileSpec(IScopeContext context, String text, int typeMask) {
boolean hasFileSpec(IScopeContext context, String text, int typeMask, boolean caseStrict) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we already have a typeMask, why not having a new flag controlling the behavior?

if (context.equals(manager.getContext()) || (typeMask & IGNORE_USER_DEFINED) != 0)
return hasFileSpec(text, typeMask, false);
return hasFileSpec(text, typeMask, false, caseStrict);
String[] fileSpecs = ContentTypeSettings.getFileSpecs(context, id, typeMask);
for (String fileSpec : fileSpecs)
if (text.equalsIgnoreCase(fileSpec))
return true;
// no user defined association... try built-in
return hasFileSpec(text, typeMask | IGNORE_PRE_DEFINED, false);
return hasFileSpec(text, typeMask | IGNORE_PRE_DEFINED, false, caseStrict);
}

/**
Expand All @@ -397,11 +412,11 @@ boolean hasFileSpec(IScopeContext context, String text, int typeMask) {
* FILE_NAME_SPEC or FILE_EXTENSION_SPEC or FILE_REGEXP_SPEC
* @return true if this file spec has already been added, false otherwise
*/
boolean hasFileSpec(String text, int typeMask, boolean strict) {
boolean hasFileSpec(String text, int typeMask, boolean typeStrict, boolean caseStrict) {
if (fileSpecs.isEmpty())
return false;
for (FileSpec spec : fileSpecs) {
if (spec.equals(text, typeMask, strict))
if (spec.equals(text, typeMask, typeStrict, caseStrict))
return true;
}
return false;
Expand All @@ -416,7 +431,7 @@ public int hashCode() {
* Adds a user-defined or pre-defined file spec.
*/
boolean internalAddFileSpec(String fileSpec, int typeMask) {
if (hasFileSpec(fileSpec, typeMask, false))
if (hasFileSpec(fileSpec, typeMask, false, true))
return false;
FileSpec newFileSpec = createFileSpec(fileSpec, typeMask);
if ((typeMask & ContentType.SPEC_USER_DEFINED) == 0) {
Expand Down Expand Up @@ -480,15 +495,15 @@ BasicDescription internalGetDescriptionFor(ILazySource buffer, QualifiedName[] o
return description;
}

byte internalIsAssociatedWith(String fileName, IScopeContext context) {
if (hasFileSpec(context, fileName, FILE_NAME_SPEC))
byte internalIsAssociatedWith(String fileName, boolean caseStrict, IScopeContext context) {
if (hasFileSpec(context, fileName, FILE_NAME_SPEC, caseStrict))
return ASSOCIATED_BY_NAME;
String fileExtension = ContentTypeManager.getFileExtension(fileName);
if (hasFileSpec(context, fileExtension, FILE_EXTENSION_SPEC))
if (hasFileSpec(context, fileExtension, FILE_EXTENSION_SPEC, caseStrict))
return ASSOCIATED_BY_EXTENSION;
// if does not have built-in file specs, delegate to parent (if any)
if (!hasBuiltInAssociations() && baseType != null)
return baseType.internalIsAssociatedWith(fileName, context);
return baseType.internalIsAssociatedWith(fileName, caseStrict, context);
return NOT_ASSOCIATED;
}

Expand Down Expand Up @@ -523,12 +538,22 @@ boolean isAlias() {

@Override
public boolean isAssociatedWith(String fileName) {
return isAssociatedWith(fileName, manager.getContext());
return isAssociatedWith(fileName, false, manager.getContext());
}

@Override
public boolean isAssociatedWith(String fileName, boolean caseStrict) {
return isAssociatedWith(fileName, caseStrict, manager.getContext());
}

@Override
public boolean isAssociatedWith(String fileName, IScopeContext context) {
return internalIsAssociatedWith(fileName, context) != NOT_ASSOCIATED;
return internalIsAssociatedWith(fileName, false, context) != NOT_ASSOCIATED;
}

@Override
public boolean isAssociatedWith(String fileName, boolean caseStrict, IScopeContext context) {
return internalIsAssociatedWith(fileName, caseStrict, context) != NOT_ASSOCIATED;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,35 @@
*******************************************************************************/
package org.eclipse.core.internal.content;

import java.io.*;
import java.util.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.content.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.content.IContentDescriber;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.core.runtime.content.IContentTypeManager.ISelectionPolicy;
import org.eclipse.core.runtime.content.IContentTypeSettings;
import org.eclipse.core.runtime.content.ITextContentDescriber;
import org.eclipse.core.runtime.content.XMLRootElementContentDescriber;

Check warning on line 44 in runtime/bundles/org.eclipse.core.contenttype/src/org/eclipse/core/internal/content/ContentTypeCatalog.java

View check run for this annotation

Jenkins - Eclipse Platform / Compiler and API Tools

Deprecation

NORMAL: The type XMLRootElementContentDescriber is deprecated
import org.eclipse.core.runtime.content.XMLRootElementContentDescriber2;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.osgi.util.NLS;

Expand Down Expand Up @@ -652,7 +674,7 @@
typeMask ^= (IContentType.IGNORE_PRE_DEFINED | IContentType.IGNORE_USER_DEFINED);
for (Iterator<ContentType> i = contentTypes.iterator(); i.hasNext();) {
ContentType contentType = i.next();
if (!contentType.hasFileSpec(text, typeMask, true))
if (!contentType.hasFileSpec(text, typeMask, true, false))
i.remove();
}
}
Expand Down Expand Up @@ -708,21 +730,16 @@
for (ContentType root : source) {
// From a given content type, check if it matches, and
// include any children that match as well.
internalAccept(new ContentTypeVisitor() {
@Override
public int visit(ContentType type) {
if (type != root && type.hasBuiltInAssociations())
// this content type has built-in associations - visit it later as root
return RETURN;
if (type == root && !type.hasFileSpec(context, fileSpecText, fileSpecType))
// it is the root and does not match the file name - do not add it nor look into its children
return RETURN;
// either the content type is the root and matches the file name or
// is a sub content type and does not have built-in files specs
if (!existing.contains(type))
destination.add(type);
return CONTINUE;
}
internalAccept(type -> {
if ((type != root && type.hasBuiltInAssociations())
|| (type == root && !type.hasFileSpec(context, fileSpecText, fileSpecType, false)))
// it is the root and does not match the file name - do not add it nor look into its children
return ContentTypeVisitor.RETURN;
// either the content type is the root and matches the file name or
// is a sub content type and does not have built-in files specs
if (!existing.contains(type))
destination.add(type);
return ContentTypeVisitor.CONTINUE;
}, root);
}
return destination;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
*******************************************************************************/
package org.eclipse.core.internal.content;

import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.ref.SoftReference;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.content.*;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeSettings;
import org.eclipse.core.runtime.preferences.IScopeContext;

/**
Expand Down Expand Up @@ -169,13 +173,25 @@ public int hashCode() {
@Override
public boolean isAssociatedWith(String fileName) {
final IContentType target = getTarget();
return (target != null) ? target.isAssociatedWith(fileName) : false;
return (target != null) ? target.isAssociatedWith(fileName, false) : false;
}

@Override
public boolean isAssociatedWith(String fileName, IScopeContext context) {
final IContentType target = getTarget();
return (target != null) ? target.isAssociatedWith(fileName, context) : false;
return (target != null) ? target.isAssociatedWith(fileName, false, context) : false;
}

@Override
public boolean isAssociatedWith(String fileName, boolean caseStrict) {
final IContentType target = getTarget();
return (target != null) ? target.isAssociatedWith(fileName, caseStrict) : false;
}

@Override
public boolean isAssociatedWith(String fileName, boolean caseStrict, IScopeContext context) {
final IContentType target = getTarget();
return (target != null) ? target.isAssociatedWith(fileName, caseStrict, context) : false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ public boolean equals(Object other) {
if (!(other instanceof FileSpec))
return false;
FileSpec otherFileSpec = (FileSpec) other;
return equals(text, otherFileSpec.getType(), false);
return equals(text, otherFileSpec.getType(), false, false);
}

public boolean equals(final String text, final int otherType, final boolean strict) {
return ((!strict && getBasicType(type) == getBasicType(otherType)) || type == otherType) && this.text.equalsIgnoreCase(text);
public boolean equals(final String text, final int otherType, final boolean typeStrict, final boolean caseStrict) {
boolean textMatch = caseStrict ? this.text.equals(text) : this.text.equalsIgnoreCase(text);
return ((!typeStrict && getBasicType(type) == getBasicType(otherType)) || type == otherType) && textMatch;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
*******************************************************************************/
package org.eclipse.core.runtime.content;

import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.preferences.IScopeContext;
Expand Down Expand Up @@ -167,26 +169,56 @@ public interface IContentType extends IContentTypeSettings {
String getName();

/**
* Returns whether this content type is associated with the
* given file name.
* Returns whether this content type is associated with the given file name. The
* association is done ignoring case "c"=="C"
*
* @param fileName the file name
* @return <code>true</code> if this content type is associated with
* the given file name, <code>false</code> otherwise
* @return <code>true</code> if this content type is associated with the given
* file name, <code>false</code> otherwise
* @see #isAssociatedWith(String, IScopeContext)
*/
@Deprecated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you deprecate it, there should be javadoc explaining what to use instead.

I wonder though, why deprecate it instead of having a default method that calls the new method with true, which has been the behavior of the past? But then, you've deprecated two methods and replaced them with a single method, so if I have a string but not a scope context, what will I do to fix the deprecation warning?

boolean isAssociatedWith(String fileName);

/**
* Returns whether this content type is associated with the
* given file name in the given preference scope.
* Returns whether this content type is associated with the given file name.
*
* @param fileName the file name
* @param caseStrict if true the string comparison is case sensitive else the
* comparison is ignoring case
*
* @return <code>true</code> if this content type is associated with the given
* file name, <code>false</code> otherwise
* @see #isAssociatedWith(String, IScopeContext)
* @since 3.10
*/
boolean isAssociatedWith(String fileName, boolean caseStrict);

/**
* Returns whether this content type is associated with the given file name in
* the given preference scope.
*
* @param fileName the file name
* @param caseStrict if true the string comparison is case sensitive else the
* comparison is ignoring case
* @param context a preference scope context
* @return <code>true</code> if this content type is associated with the given
* file name, <code>false</code> otherwise
* @since 3.10
*/
boolean isAssociatedWith(String fileName, boolean caseStrict, IScopeContext context);

/**
* Returns whether this content type is associated with the given file name in
* the given preference scope. The association is done ignoring case "c"=="C"
*
* @param fileName the file name
* @param context a preference scope context
* @return <code>true</code> if this content type is associated with
* the given file name, <code>false</code> otherwise
* @param context a preference scope context
* @return <code>true</code> if this content type is associated with the given
* file name, <code>false</code> otherwise
* @since 3.1
*/
@Deprecated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you deprecate it, there should be javadoc explaining what to use instead.

boolean isAssociatedWith(String fileName, IScopeContext context);

/**
Expand Down
Loading