diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.classpath b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.classpath new file mode 100644 index 00000000000..375961e4d61 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.gitignore b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.gitignore new file mode 100644 index 00000000000..14435d8efa9 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.gitignore @@ -0,0 +1 @@ +OSGI-INF/org.eclipse.*.xml diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.project b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.project new file mode 100644 index 00000000000..c4b531be21f --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.project @@ -0,0 +1,34 @@ + + + org.eclipse.core.runtime.bundlegroups + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.api.tools.apiAnalysisBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.pde.api.tools.apiAnalysisNature + + diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.core.resources.prefs b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000000..99f26c0203a --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.core.runtime.prefs b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 00000000000..5a0ad22d2a7 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +line.separator=\n diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.jdt.core.prefs b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..3a8fc308afb --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,126 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnull.secondary= +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary= +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullable.secondary= +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.doc.comment.support=enabled +org.eclipse.jdt.core.compiler.problem.APILeak=warning +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=warning +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning +org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore +org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=disabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public +org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled +org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning +org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning +org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled +org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedImport=error +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=error +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error +org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.jdt.ui.prefs b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000000..81f11511252 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,147 @@ +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +org.eclipse.jdt.ui.ondemandthreshold=99 +org.eclipse.jdt.ui.staticondemandthreshold=99 +sp_cleanup.add_all=false +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.also_simplify_lambda=true +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.array_with_curly=false +sp_cleanup.arrays_fill=false +sp_cleanup.bitwise_conditional_expression=false +sp_cleanup.boolean_literal=false +sp_cleanup.boolean_value_rather_than_comparison=true +sp_cleanup.break_loop=false +sp_cleanup.collection_cloning=false +sp_cleanup.comparing_on_criteria=false +sp_cleanup.comparison_statement=false +sp_cleanup.controlflow_merge=false +sp_cleanup.convert_functional_interfaces=true +sp_cleanup.convert_to_enhanced_for_loop=true +sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=true +sp_cleanup.convert_to_switch_expressions=false +sp_cleanup.correct_indentation=false +sp_cleanup.do_while_rather_than_while=false +sp_cleanup.double_negation=false +sp_cleanup.else_if=false +sp_cleanup.embedded_if=false +sp_cleanup.evaluate_nullable=false +sp_cleanup.extract_increment=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=true +sp_cleanup.hash=false +sp_cleanup.if_condition=false +sp_cleanup.insert_inferred_type_arguments=false +sp_cleanup.instanceof=false +sp_cleanup.instanceof_keyword=false +sp_cleanup.invert_equals=false +sp_cleanup.join=false +sp_cleanup.lazy_logical_operator=false +sp_cleanup.make_local_variable_final=true +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=false +sp_cleanup.map_cloning=false +sp_cleanup.merge_conditional_blocks=false +sp_cleanup.multi_catch=false +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.no_string_creation=false +sp_cleanup.no_super=false +sp_cleanup.number_suffix=false +sp_cleanup.objects_equals=false +sp_cleanup.on_save_use_additional_actions=true +sp_cleanup.one_if_rather_than_duplicate_blocks_that_fall_through=false +sp_cleanup.operand_factorization=false +sp_cleanup.organize_imports=true +sp_cleanup.overridden_assignment=false +sp_cleanup.overridden_assignment_move_decl=true +sp_cleanup.plain_replacement=false +sp_cleanup.precompile_regex=false +sp_cleanup.primitive_comparison=false +sp_cleanup.primitive_parsing=false +sp_cleanup.primitive_rather_than_wrapper=true +sp_cleanup.primitive_serialization=false +sp_cleanup.pull_out_if_from_if_else=false +sp_cleanup.pull_up_assignment=false +sp_cleanup.push_down_negation=false +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=true +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.reduce_indentation=false +sp_cleanup.redundant_comparator=false +sp_cleanup.redundant_falling_through_block_end=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_redundant_modifiers=false +sp_cleanup.remove_redundant_semicolons=true +sp_cleanup.remove_redundant_type_arguments=true +sp_cleanup.remove_trailing_whitespaces=true +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_array_creation=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=true +sp_cleanup.remove_unused_imports=true +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_method_parameters=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.replace_deprecated_calls=false +sp_cleanup.return_expression=false +sp_cleanup.simplify_lambda_expression_and_method_ref=true +sp_cleanup.single_used_field=false +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.standard_comparison=false +sp_cleanup.static_inner_class=false +sp_cleanup.strictly_equal_or_different=false +sp_cleanup.stringbuffer_to_stringbuilder=false +sp_cleanup.stringbuilder=false +sp_cleanup.stringbuilder_for_local_vars=true +sp_cleanup.stringconcat_stringbuffer_stringbuilder=false +sp_cleanup.stringconcat_to_textblock=false +sp_cleanup.substring=false +sp_cleanup.switch=false +sp_cleanup.system_property=false +sp_cleanup.system_property_boolean=false +sp_cleanup.system_property_file_encoding=false +sp_cleanup.system_property_file_separator=false +sp_cleanup.system_property_line_separator=false +sp_cleanup.system_property_path_separator=false +sp_cleanup.ternary_operator=false +sp_cleanup.try_with_resource=false +sp_cleanup.unlooped_while=false +sp_cleanup.unreachable_block=false +sp_cleanup.use_anonymous_class_creation=false +sp_cleanup.use_autoboxing=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_directly_map_method=false +sp_cleanup.use_lambda=true +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_string_is_blank=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true +sp_cleanup.use_unboxing=false +sp_cleanup.use_var=false +sp_cleanup.useless_continue=false +sp_cleanup.useless_return=false +sp_cleanup.valueof_rather_than_instantiation=false diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.pde.ds.annotations.prefs b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.pde.ds.annotations.prefs new file mode 100644 index 00000000000..5faf08b7d5c --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/.settings/org.eclipse.pde.ds.annotations.prefs @@ -0,0 +1,7 @@ +dsVersion=V1_4 +eclipse.preferences.version=1 +enabled=true +generateBundleActivationPolicyLazy=true +path=OSGI-INF +validationErrorLevel=error +validationErrorLevel.missingImplicitUnbindMethod=error diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/META-INF/MANIFEST.MF b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..ca423529e0a --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/META-INF/MANIFEST.MF @@ -0,0 +1,16 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.eclipse.core.runtime.bundlegroups;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: %providerName +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime;bundle-version="3.29.0" +Bundle-RequiredExecutionEnvironment: JavaSE-21 +Import-Package: javax.xml.parsers, + org.w3c.dom, + org.xml.sax, + org.xml.sax.helpers +Bundle-ActivationPolicy: lazy +Automatic-Module-Name: org.eclipse.core.runtime.bundlegroups +Service-Component: OSGI-INF/org.eclipse.core.internal.runtime.bundlegroups.FeatureBundleGroupProvider.xml diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/about.html b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/about.html new file mode 100644 index 00000000000..164f781a8fd --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/about.html @@ -0,0 +1,36 @@ + + + + +About + + +

About This Content

+ +

November 30, 2017

+

License

+ +

+ The Eclipse Foundation makes available all content in this plug-in + ("Content"). Unless otherwise indicated below, the Content + is provided to you under the terms and conditions of the Eclipse + Public License Version 2.0 ("EPL"). A copy of the EPL is + available at http://www.eclipse.org/legal/epl-2.0. + For purposes of the EPL, "Program" will mean the Content. +

+ +

+ If you did not receive this Content directly from the Eclipse + Foundation, the Content is being redistributed by another party + ("Redistributor") and different terms and conditions may + apply to your use of any object code in the Content. Check the + Redistributor's license that was provided with the Content. If no such + license exists, contact the Redistributor. Unless otherwise indicated + below, the terms and conditions of the EPL still apply to any source + code in the Content and such source code may be obtained at http://www.eclipse.org. +

+ + + \ No newline at end of file diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/build.properties b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/build.properties new file mode 100644 index 00000000000..9b2f9357689 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/build.properties @@ -0,0 +1,21 @@ +############################################################################### +# Copyright (c) 2026 Lars Vogel and others. +# +# This program and the accompanying materials +# are made available under the terms of the Eclipse Public License 2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Lars Vogel - initial API and implementation +############################################################################### +bin.includes = META-INF/,\ + .,\ + about.html,\ + plugin.properties,\ + OSGI-INF/ +src.includes = about.html +source.. = src/ +output.. = bin/ diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/plugin.properties b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/plugin.properties new file mode 100644 index 00000000000..756b8e0331e --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/plugin.properties @@ -0,0 +1,15 @@ +############################################################################### +# Copyright (c) 2026 Lars Vogel and others. +# +# This program and the accompanying materials +# are made available under the terms of the Eclipse Public License 2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# Lars Vogel - initial API and implementation +############################################################################### +pluginName= Installed Feature Bundle Groups +providerName= Eclipse.org diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/AboutInfo.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/AboutInfo.java similarity index 99% rename from update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/AboutInfo.java rename to runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/AboutInfo.java index 5d3c412d7ef..0169c63b8ee 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/AboutInfo.java +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/AboutInfo.java @@ -11,7 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.update.internal.configurator.branding; +package org.eclipse.core.internal.runtime.bundlegroups; import java.net.URL; import java.util.Hashtable; diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureBundleGroup.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureBundleGroup.java new file mode 100644 index 00000000000..bd8fcc7c985 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureBundleGroup.java @@ -0,0 +1,262 @@ +/******************************************************************************* + * Copyright (c) 2026 Lars Vogel and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Lars Vogel - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime.bundlegroups; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.StringTokenizer; + +import org.eclipse.core.runtime.IBundleGroup; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.Platform; +import org.osgi.framework.Bundle; + +/** + * A bundle group backed by an installed feature. The feature identity comes + * from platform.xml, everything else is read from the feature and its branding + * bundle on demand. + */ +public class FeatureBundleGroup implements IBundleGroup, IBundleGroupConstants, IProductConstants { + + private static final String FEATURE_XML = "feature.xml"; //$NON-NLS-1$ + private static final String FEATURE_PROPERTIES = "feature"; //$NON-NLS-1$ + private static final String KEY_PREFIX = "%"; //$NON-NLS-1$ + private static final String KEY_DOUBLE_PREFIX = "%%"; //$NON-NLS-1$ + + private final String id; + private final String version; + private final String pluginIdentifier; + private final String pluginVersion; + private final URI featureLocation; + + private AboutInfo branding; + private FeatureManifest manifest; + private boolean fullyParsed; + private ResourceBundle resourceBundle; + private boolean resourceBundleLoaded; + + FeatureBundleGroup(String id, String version, String pluginIdentifier, String pluginVersion, URI featureLocation) { + this.id = id; + this.version = version; + this.pluginIdentifier = pluginIdentifier; + this.pluginVersion = pluginVersion; + this.featureLocation = featureLocation; + } + + /** + * A feature contributes a bundle group only when its branding bundle is + * installed. + */ + boolean hasBranding() { + String bundleId = getFeaturePluginIdentifier(); + return bundleId != null && Platform.getBundle(bundleId) != null; + } + + private String getFeaturePluginIdentifier() { + return pluginIdentifier != null && !pluginIdentifier.isEmpty() ? pluginIdentifier : id; + } + + @Override + public String getIdentifier() { + return id; + } + + @Override + public String getVersion() { + return version; + } + + @Override + public String getName() { + return getBranding().getProductName(); + } + + @Override + public String getProviderName() { + return getBranding().getProviderName(); + } + + @Override + public String getDescription() { + FeatureManifest parsed = fullParse(); + return parsed == null ? null : getResourceString(parsed.description); + } + + @Override + public Bundle[] getBundles() { + FeatureManifest parsed = fullParse(); + if (parsed == null) { + return new Bundle[0]; + } + List bundles = new ArrayList<>(parsed.pluginIds.size()); + for (String pluginId : parsed.pluginIds) { + Bundle bundle = Platform.getBundle(pluginId); + if (bundle != null) { + bundles.add(bundle); + } + } + return bundles.toArray(new Bundle[bundles.size()]); + } + + @Override + public String getProperty(String key) { + if (key == null) { + return null; + } + AboutInfo info = getBranding(); + + // IBundleGroupConstants + if (key.equals(FEATURE_IMAGE)) { + return toExternalForm(info.getFeatureImageURL()); + } else if (key.equals(TIPS_AND_TRICKS_HREF)) { + return info.getTipsAndTricksHref(); + } else if (key.equals(IBundleGroupConstants.WELCOME_PAGE)) { // same value is used by product and bundle group + return toExternalForm(info.getWelcomePageURL()); + } else if (key.equals(WELCOME_PERSPECTIVE)) { + return info.getWelcomePerspectiveId(); + } else if (key.equals(BRANDING_BUNDLE_ID)) { + return pluginIdentifier; + } else if (key.equals(BRANDING_BUNDLE_VERSION)) { + return pluginVersion; + } else if (key.equals(APP_NAME)) { + return info.getAppName(); + } else if (key.equals(ABOUT_TEXT)) { + return info.getAboutText(); + } else if (key.equals(ABOUT_IMAGE)) { + return toExternalForm(info.getAboutImageURL()); + } else if (key.equals(WINDOW_IMAGE)) { + return toExternalForm(info.getWindowImageURL()); + } else if (key.equals(WINDOW_IMAGES)) { + URL[] urls = info.getWindowImagesURLs(); + if (urls == null) { + return null; + } + StringBuilder windowImagesURLs = new StringBuilder(); + for (int i = 0; i < urls.length; i++) { + windowImagesURLs.append(urls[i].toExternalForm()); + if (i != urls.length - 1) { + windowImagesURLs.append(','); + } + } + return windowImagesURLs.toString(); + } else if (key.equals(LICENSE_HREF)) { + return getLicenseURL(); + } + + return null; + } + + private static String toExternalForm(URL url) { + return url == null ? null : url.toExternalForm(); + } + + private synchronized AboutInfo getBranding() { + if (branding == null) { + branding = AboutInfo.readFeatureInfo(id, version, getFeaturePluginIdentifier()); + } + return branding; + } + + private String getLicenseURL() { + FeatureManifest parsed = fullParse(); + if (parsed == null || parsed.licenseURL == null) { + return null; + } + String resolved = getResourceString(parsed.licenseURL); + if (resolved.startsWith("http://") || resolved.startsWith("https://")) { //$NON-NLS-1$ //$NON-NLS-2$ + return resolved; + } + return featureLocation.resolve(resolved).toString(); + } + + private synchronized FeatureManifest fullParse() { + if (!fullyParsed) { + fullyParsed = true; + try { + manifest = FeatureXmlParser.parse(featureLocation.resolve(FEATURE_XML).toURL(), false); + } catch (MalformedURLException | IllegalArgumentException e) { + ILog.of(FeatureBundleGroup.class).error("Cannot locate the feature.xml of " + id, e); //$NON-NLS-1$ + } + } + return manifest; + } + + /* + * Resolves a %key reference against the feature.properties of this feature. + */ + private String getResourceString(String value) { + if (value == null) { + return null; + } + String s = value.trim(); + if (s.isEmpty() || !s.startsWith(KEY_PREFIX)) { + return value; + } + if (s.startsWith(KEY_DOUBLE_PREFIX)) { + return s.substring(1); + } + + int index = s.indexOf(' '); + String key = index == -1 ? s : s.substring(0, index); + String defaultValue = index == -1 ? s : s.substring(index + 1); + + ResourceBundle bundle = getResourceBundle(); + if (bundle == null) { + return defaultValue; + } + try { + return bundle.getString(key.substring(1)); + } catch (MissingResourceException e) { + return defaultValue; + } + } + + private synchronized ResourceBundle getResourceBundle() { + if (!resourceBundleLoaded) { + resourceBundleLoaded = true; + try { + ClassLoader loader = new URLClassLoader(new URL[] { featureLocation.toURL() }, null); + resourceBundle = ResourceBundle.getBundle(FEATURE_PROPERTIES, getDefaultLocale(), loader); + } catch (MissingResourceException | MalformedURLException | IllegalArgumentException e) { + // features are not required to be translated + } + } + return resourceBundle; + } + + private static Locale getDefaultLocale() { + String nl = Platform.getNL(); + if (nl == null) { + return Locale.getDefault(); + } + StringTokenizer locales = new StringTokenizer(nl, "_"); //$NON-NLS-1$ + switch (locales.countTokens()) { + case 1: + return Locale.of(locales.nextToken()); + case 2: + return Locale.of(locales.nextToken(), locales.nextToken()); + case 3: + return Locale.of(locales.nextToken(), locales.nextToken(), locales.nextToken()); + default: + return Locale.getDefault(); + } + } +} diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureBundleGroupProvider.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureBundleGroupProvider.java new file mode 100644 index 00000000000..c4f6fec1577 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureBundleGroupProvider.java @@ -0,0 +1,170 @@ +/******************************************************************************* + * Copyright (c) 2026 Lars Vogel and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Lars Vogel - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime.bundlegroups; + +import java.io.File; +import java.io.FileFilter; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.internal.runtime.bundlegroups.platformxml.Configuration; +import org.eclipse.core.internal.runtime.bundlegroups.platformxml.ConfigurationParser; +import org.eclipse.core.internal.runtime.bundlegroups.platformxml.Feature; +import org.eclipse.core.internal.runtime.bundlegroups.platformxml.Site; +import org.eclipse.core.runtime.IBundleGroup; +import org.eclipse.core.runtime.IBundleGroupProvider; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.Platform; +import org.eclipse.osgi.service.datalocation.Location; +import org.osgi.service.component.annotations.Component; + +/** + * Contributes the installed features as bundle groups. The feature list comes + * from the platform.xml written at provisioning time, so no plug-in has to be + * inspected to build it. + */ +@Component(service = IBundleGroupProvider.class) +public class FeatureBundleGroupProvider implements IBundleGroupProvider { + + private static final String PLATFORM_XML = "org.eclipse.update/platform.xml"; //$NON-NLS-1$ + private static final String FEATURES = "features"; //$NON-NLS-1$ + private static final String FEATURE_XML = "feature.xml"; //$NON-NLS-1$ + + private List cachedFeatures; + private long cachedTimestamp = -1; + + @Override + public String getName() { + return Messages.BundleGroupProvider; + } + + @Override + public synchronized IBundleGroup[] getBundleGroups() { + File platformXml = findPlatformXml(); + long timestamp = platformXml == null ? 0 : platformXml.lastModified(); + if (cachedFeatures == null || timestamp != cachedTimestamp) { + cachedFeatures = readFeatures(platformXml); + cachedTimestamp = timestamp; + } + // the branding bundle of a feature can be installed after the feature was read + return cachedFeatures.stream().filter(FeatureBundleGroup::hasBranding).toArray(IBundleGroup[]::new); + } + + private static List readFeatures(File platformXml) { + URL installArea = getInstallArea(); + List features = new ArrayList<>(); + Configuration configuration = platformXml == null ? null + : ConfigurationParser.parse(platformXml, installArea); + if (configuration == null) { + collectFromInstallArea(installArea, features); + } else { + for (Site site : configuration.getSites()) { + collectFromSite(site, features); + } + } + return features; + } + + private static void collectFromSite(Site site, List features) { + URI siteLocation = toURI(site.getUrl()); + if (siteLocation == null) { + return; + } + for (Feature feature : site.getFeatures()) { + if (feature.getId() == null) { + continue; + } + String featureURL = feature.getUrl(); + if (featureURL == null) { + featureURL = FEATURES + "/" + feature.getId() + "_" + feature.getVersion() + "/"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + features.add(new FeatureBundleGroup(feature.getId(), feature.getVersion(), feature.getPluginIdentifier(), + feature.getPluginVersion(), siteLocation.resolve(featureURL))); + } + } + + /* + * Without a platform.xml the installed features can only be found by looking at + * the features directory of the install area. + */ + private static void collectFromInstallArea(URL installArea, List features) { + if (installArea == null || !"file".equals(installArea.getProtocol())) { //$NON-NLS-1$ + return; + } + File featuresDir = new File(installArea.getFile().replace('/', File.separatorChar), FEATURES); + File[] dirs = featuresDir + .listFiles((FileFilter) f -> f.isDirectory() && new File(f, FEATURE_XML).exists()); + if (dirs == null) { + return; + } + for (File dir : dirs) { + try { + FeatureManifest manifest = FeatureXmlParser.parse(new File(dir, FEATURE_XML).toURI().toURL(), true); + if (manifest != null) { + features.add(new FeatureBundleGroup(manifest.id, manifest.version, manifest.pluginIdentifier, + manifest.version, dir.toURI())); + } + } catch (MalformedURLException e) { + ILog.of(FeatureBundleGroupProvider.class).error("Cannot read the feature in " + dir, e); //$NON-NLS-1$ + } + } + } + + /* + * The platform.xml of the configuration area, falling back to the one of a + * shared install. + */ + private static File findPlatformXml() { + Location configuration = Platform.getConfigurationLocation(); + if (configuration == null) { + return null; + } + File file = toPlatformXml(configuration); + if (file != null && file.exists()) { + return file; + } + Location parent = configuration.getParentLocation(); + File parentFile = parent == null ? null : toPlatformXml(parent); + return parentFile != null && parentFile.exists() ? parentFile : null; + } + + private static File toPlatformXml(Location location) { + URL url = location.getURL(); + if (url == null || !"file".equals(url.getProtocol())) { //$NON-NLS-1$ + return null; + } + return new File(url.getFile().replace('/', File.separatorChar), PLATFORM_XML); + } + + private static URL getInstallArea() { + Location install = Platform.getInstallLocation(); + return install == null ? null : install.getURL(); + } + + private static URI toURI(String encodedURI) { + if (encodedURI == null) { + return null; + } + try { + return new URI(encodedURI); + } catch (URISyntaxException e) { + ILog.of(FeatureBundleGroupProvider.class).error("Cannot resolve the site " + encodedURI, e); //$NON-NLS-1$ + return null; + } + } +} diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureManifest.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureManifest.java new file mode 100644 index 00000000000..9c8a52faa72 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureManifest.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2026 Lars Vogel and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Lars Vogel - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime.bundlegroups; + +import java.util.ArrayList; +import java.util.List; + +/** + * The contents of a feature.xml file, as far as a bundle group needs them. + */ +class FeatureManifest { + + String id; + String version; + String pluginIdentifier; + String application; + boolean primary; + String description; + String licenseURL; + final List pluginIds = new ArrayList<>(); +} diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureXmlParser.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureXmlParser.java new file mode 100644 index 00000000000..4a8f2cd27bb --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/FeatureXmlParser.java @@ -0,0 +1,195 @@ +/******************************************************************************* + * Copyright (c) 2000, 2017 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime.bundlegroups; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.StringTokenizer; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; + +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.Platform; +import org.eclipse.osgi.util.NLS; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * Parses a feature.xml file. In header mode parsing stops after the feature + * element, which is all the platform.xml fallback needs. + */ +class FeatureXmlParser extends DefaultHandler { + + private static final SAXException STOP_PARSING = new SAXException(""); //$NON-NLS-1$ + + private final boolean headerOnly; + private final FeatureManifest manifest = new FeatureManifest(); + private final StringBuilder description = new StringBuilder(); + private boolean isDescription; + + static FeatureManifest parse(URL featureXML, boolean headerOnly) { + FeatureXmlParser handler = new FeatureXmlParser(headerOnly); + SAXParser parser; + try { + parser = createParser(); + } catch (ParserConfigurationException | SAXException e) { + ILog.of(FeatureXmlParser.class).error("Failed to create a parser for " + featureXML, e); //$NON-NLS-1$ + return null; + } + try (InputStream in = featureXML.openStream()) { + parser.parse(new InputSource(in), handler); + } catch (SAXException e) { + if (e != STOP_PARSING) { + return handler.manifest.id == null ? null : handler.manifest; + } + } catch (IOException e) { + return null; + } + return handler.manifest.id == null ? null : handler.manifest; + } + + @SuppressWarnings("restriction") + private static SAXParser createParser() throws ParserConfigurationException, SAXException { + return org.eclipse.core.internal.runtime.XmlProcessorFactory.createSAXParserWithErrorOnDOCTYPE(true); + } + + private FeatureXmlParser(boolean headerOnly) { + this.headerOnly = headerOnly; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if ("feature".equals(localName)) { //$NON-NLS-1$ + processFeature(attributes); + if (headerOnly) { + throw STOP_PARSING; + } + } else if ("plugin".equals(localName)) { //$NON-NLS-1$ + processPlugin(attributes); + } else if ("description".equals(localName)) { //$NON-NLS-1$ + isDescription = true; + } else if ("license".equals(localName)) { //$NON-NLS-1$ + manifest.licenseURL = attributes.getValue("url"); //$NON-NLS-1$ + } + } + + private void processFeature(Attributes attributes) { + String id = attributes.getValue("id"); //$NON-NLS-1$ + String version = attributes.getValue("version"); //$NON-NLS-1$ + if (id == null || id.trim().isEmpty() || version == null || version.trim().isEmpty()) { + ILog.of(FeatureXmlParser.class).warn(NLS.bind(Messages.FeatureParser_IdOrVersionInvalid, id, version)); + return; + } + if (!isValidEnvironment(attributes)) { + return; + } + manifest.id = id; + manifest.version = version; + manifest.pluginIdentifier = attributes.getValue("plugin"); //$NON-NLS-1$ + manifest.application = attributes.getValue("application"); //$NON-NLS-1$ + manifest.primary = "true".equals(attributes.getValue("primary")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private void processPlugin(Attributes attributes) { + String id = attributes.getValue("id"); //$NON-NLS-1$ + String version = attributes.getValue("version"); //$NON-NLS-1$ + if (id == null || id.trim().isEmpty() || version == null || version.trim().isEmpty()) { + ILog.of(FeatureXmlParser.class).warn(NLS.bind(Messages.FeatureParser_IdOrVersionInvalid, id, version)); + return; + } + if (!isValidEnvironment(attributes)) { + return; + } + manifest.pluginIds.add(id); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + if (isDescription) { + description.append(ch, start, length); + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + if ("description".equals(localName)) { //$NON-NLS-1$ + isDescription = false; + manifest.description = description.toString().trim(); + } + } + + private static boolean isValidEnvironment(Attributes attributes) { + String os = attributes.getValue("os"); //$NON-NLS-1$ + String ws = attributes.getValue("ws"); //$NON-NLS-1$ + String arch = attributes.getValue("arch"); //$NON-NLS-1$ + String nl = attributes.getValue("nl"); //$NON-NLS-1$ + if (os != null && !isMatching(os, Platform.getOS())) { + return false; + } + if (ws != null && !isMatching(ws, Platform.getWS())) { + return false; + } + if (arch != null && !isMatching(arch, Platform.getOSArch())) { + return false; + } + if (nl != null && !isMatchingLocale(nl, Platform.getNL())) { + return false; + } + return true; + } + + private static boolean isMatching(String candidateValues, String siteValues) { + if (siteValues == null) { + return false; + } + if ("*".equalsIgnoreCase(candidateValues)) { //$NON-NLS-1$ + return true; + } + siteValues = siteValues.toUpperCase(); + StringTokenizer stok = new StringTokenizer(candidateValues, ","); //$NON-NLS-1$ + while (stok.hasMoreTokens()) { + String token = stok.nextToken().toUpperCase(); + if (siteValues.contains(token)) { + return true; + } + } + return false; + } + + private static boolean isMatchingLocale(String candidateValues, String locale) { + if (locale == null) { + return false; + } + if ("*".equalsIgnoreCase(candidateValues)) { //$NON-NLS-1$ + return true; + } + locale = locale.toUpperCase(); + candidateValues = candidateValues.toUpperCase(); + StringTokenizer stok = new StringTokenizer(candidateValues, ","); //$NON-NLS-1$ + while (stok.hasMoreTokens()) { + String candidate = stok.nextToken(); + if (locale.indexOf(candidate) == 0) { + return true; + } + if (candidate.indexOf(locale) == 0) { + return true; + } + } + return false; + } +} diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IBundleGroupConstants.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/IBundleGroupConstants.java similarity index 86% rename from update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IBundleGroupConstants.java rename to runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/IBundleGroupConstants.java index c8c78bacc36..bcedef3c09c 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IBundleGroupConstants.java +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/IBundleGroupConstants.java @@ -11,9 +11,8 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.update.internal.configurator.branding; +package org.eclipse.core.internal.runtime.bundlegroups; -import org.eclipse.update.configurator.IPlatformConfiguration; /** * These constants define the set of properties that the UI expects to @@ -55,15 +54,13 @@ public interface IBundleGroupConstants { /** * The id of the bundle group's branding bundle. * - * @see IPlatformConfiguration.IFeatureEntry#getFeaturePluginIdentifier() * @since 3.3 */ public static final String BRANDING_BUNDLE_ID= "brandingBundleId"; //$NON-NLS-1$ /** - * The version of the feature branding bundle. + * The version of the bundle group's branding bundle. * - * @see IPlatformConfiguration.IFeatureEntry#getFeaturePluginVersion() * @since 3.3 */ public static final String BRANDING_BUNDLE_VERSION= "brandingBundleVersion"; //$NON-NLS-1$ diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IProductConstants.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/IProductConstants.java similarity index 98% rename from update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IProductConstants.java rename to runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/IProductConstants.java index 2ce1a3f6665..7111b183518 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IProductConstants.java +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/IProductConstants.java @@ -11,7 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.update.internal.configurator.branding; +package org.eclipse.core.internal.runtime.bundlegroups; /** * These constants define the set of properties that the UI expects to diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IniFileReader.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/IniFileReader.java similarity index 98% rename from update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IniFileReader.java rename to runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/IniFileReader.java index e42d4dac0bc..f4d48bef45d 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/branding/IniFileReader.java +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/IniFileReader.java @@ -11,7 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ -package org.eclipse.update.internal.configurator.branding; +package org.eclipse.core.internal.runtime.bundlegroups; import java.io.IOException; import java.io.InputStream; @@ -31,7 +31,6 @@ import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.osgi.util.NLS; -import org.eclipse.update.internal.configurator.Messages; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; @@ -43,7 +42,7 @@ * properties file - format being "n = some text", where n is a number. */ public class IniFileReader { - private static final String PID = "org.eclipse.update.configurator"; //$NON-NLS-1$ + private static final String PID = "org.eclipse.core.runtime.bundlegroups"; //$NON-NLS-1$ private static final Status OK_STATUS = new Status(IStatus.OK, PID, 0, "", null); //$NON-NLS-1$ private static final String KEY_PREFIX = "%"; //$NON-NLS-1$ private static final String KEY_DOUBLE_PREFIX = "%%"; //$NON-NLS-1$ diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/Messages.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/Messages.java new file mode 100644 index 00000000000..3c08954706e --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/Messages.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime.bundlegroups; + +import org.eclipse.osgi.util.NLS; + +public final class Messages extends NLS { + + private static final String BUNDLE_NAME = "org.eclipse.core.internal.runtime.bundlegroups.messages";//$NON-NLS-1$ + + private Messages() { + // Do not instantiate + } + + public static String BundleGroupProvider; + public static String FeatureParser_IdOrVersionInvalid; + public static String IniFileReader_MissingDesc; + public static String IniFileReader_OpenINIError; + public static String IniFileReader_ReadIniError; + public static String IniFileReader_ReadPropError; + public static String IniFileReader_ReadMapError; + + static { + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } +} diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/messages.properties b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/messages.properties new file mode 100644 index 00000000000..67242172d1b --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/messages.properties @@ -0,0 +1,22 @@ +############################################################################### +# Copyright (c) 2000, 2008 IBM Corporation and others. +# +# This program and the accompanying materials +# are made available under the terms of the Eclipse Public License 2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/legal/epl-2.0/ +# +# SPDX-License-Identifier: EPL-2.0 +# +# Contributors: +# IBM Corporation - initial API and implementation +############################################################################### +BundleGroupProvider=Installed Features + +FeatureParser_IdOrVersionInvalid= Error parsing feature stream. The unique identifier or the version is null or empty: unique identifier=\"{0}\" version=\"{1}\". + +IniFileReader_MissingDesc = Cannot find plugin for feature {0} +IniFileReader_OpenINIError = Cannot open branding file {0} +IniFileReader_ReadIniError = Error reading branding file {0} +IniFileReader_ReadPropError = Error reading branding properties file {0} +IniFileReader_ReadMapError = Error reading mapping files {0} diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/Configuration.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/Configuration.java new file mode 100644 index 00000000000..5753448e72c --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/Configuration.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime.bundlegroups.platformxml; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.URIUtil; + +/** + * The contents of a platform.xml file. + */ +public class Configuration { + + private final List sites = new ArrayList<>(); + private String sharedUR; + private URL osgiInstallArea; + + void setSharedUR(String value) { + sharedUR = value; + } + + void setOsgiInstallArea(URL osgiInstallArea) { + this.osgiInstallArea = osgiInstallArea; + } + + /** + * The sites of this configuration, followed by those of the shared + * configuration it links to, if any. + */ + public List getSites() { + if (sharedUR == null) { + return sites; + } + List result = new ArrayList<>(sites); + Configuration parent = loadParent(); + if (parent != null) { + result.addAll(parent.getSites()); + } + return result; + } + + private Configuration loadParent() { + File location; + try { + location = URIUtil.toFile(new URI(sharedUR)); + } catch (URISyntaxException e) { + return null; + } + if (location == null) { + return null; + } + if (!location.isAbsolute()) { + File installArea = toFile(osgiInstallArea); + if (installArea == null) { + return null; + } + location = new File(installArea, location.getPath()); + } + return ConfigurationParser.parse(location, osgiInstallArea); + } + + private static File toFile(URL url) { + try { + return url == null ? null : URIUtil.toFile(URIUtil.toURI(url)); + } catch (URISyntaxException e) { + return null; + } + } + + void add(Site site) { + sites.add(site); + } +} diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/ConfigurationConstants.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/ConfigurationConstants.java new file mode 100644 index 00000000000..d241a1c4fd2 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/ConfigurationConstants.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2008 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime.bundlegroups.platformxml; + +/** + * Element and attribute names used in a platform.xml file. + */ +public interface ConfigurationConstants { + + String ELEMENT_CONFIG = "config"; //$NON-NLS-1$ + String ELEMENT_FEATURE = "feature"; //$NON-NLS-1$ + String ELEMENT_SITE = "site"; //$NON-NLS-1$ + + String ATTRIBUTE_ID = "id"; //$NON-NLS-1$ + String ATTRIBUTE_PLUGIN_IDENTIFIER = "plugin-identifier"; //$NON-NLS-1$ + String ATTRIBUTE_PLUGIN_VERSION = "plugin-version"; //$NON-NLS-1$ + String ATTRIBUTE_SHARED_UR = "shared_ur"; //$NON-NLS-1$ + String ATTRIBUTE_URL = "url"; //$NON-NLS-1$ + String ATTRIBUTE_VERSION = "version"; //$NON-NLS-1$ + +} diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/ConfigurationParser.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/ConfigurationParser.java new file mode 100644 index 00000000000..dc9cf4bf4d4 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/ConfigurationParser.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright (c) 2007, 2015 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime.bundlegroups.platformxml; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.URIUtil; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +/** + * Parser for platform.xml files. + */ +public class ConfigurationParser implements ConfigurationConstants { + static final String PLATFORM_BASE = "platform:/base/"; //$NON-NLS-1$ + private final URL osgiInstallArea; + + /* + * Parse the given file handle which points to a platform.xml file and return a + * configuration object. Returns null if the file doesn't exist or cannot be read. + */ + public static Configuration parse(File file, URL osgiInstallArea) { + return new ConfigurationParser(osgiInstallArea).internalParse(file); + } + + private ConfigurationParser(URL osgiInstallArea) { + this.osgiInstallArea = osgiInstallArea; + } + + /* + * Create a feature object based on the given DOM node. Return the new feature. + */ + private static Feature createFeature(Node node) { + Feature result = new Feature(); + String id = getAttribute(node, ATTRIBUTE_ID); + if (id != null) { + result.setId(id); + } + String url = getAttribute(node, ATTRIBUTE_URL); + if (url != null) { + result.setUrl(url); + } + String version = getAttribute(node, ATTRIBUTE_VERSION); + if (version != null) { + result.setVersion(version); + } + String pluginIdentifier = getAttribute(node, ATTRIBUTE_PLUGIN_IDENTIFIER); + if (pluginIdentifier != null) { + result.setPluginIdentifier(pluginIdentifier); + } + String pluginVersion = getAttribute(node, ATTRIBUTE_PLUGIN_VERSION); + // plug-in version is the same as the feature version if it is missing + if (pluginVersion == null) { + pluginVersion = version; + } + if (pluginVersion != null) { + result.setPluginVersion(pluginVersion); + } + return result; + } + + /* + * Create the features from the given DOM node. + */ + private static void createFeatures(Node node, Site site) { + NodeList children = node.getChildNodes(); + int size = children.getLength(); + for (int i = 0; i < size; i++) { + Node child = children.item(i); + if (child.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + if (!ELEMENT_FEATURE.equalsIgnoreCase(child.getNodeName())) { + continue; + } + site.addFeature(createFeature(child)); + } + } + + /* + * Create a site based on the given DOM node. + */ + private Site createSite(Node node) { + Site result = new Site(); + String url = getAttribute(node, ATTRIBUTE_URL); + if (url != null) { + try { + // do this to ensure the location is an encoded URI + URI uri = URIUtil.fromString(url); + URI osgiURI = osgiInstallArea != null ? URIUtil.toURI(osgiInstallArea) : null; + result.setUrl(getLocation(uri, osgiURI).toString()); + } catch (URISyntaxException e) { + result.setUrl(url); + } + } + createFeatures(node, result); + return result; + } + + /* + * Convert the given url string to an absolute url. If the string is + * platform:/base/ then return a string which represents the osgi install area. + */ + private static URI getLocation(URI location, URI osgiArea) { + if (osgiArea == null) { + return location; + } + if (PLATFORM_BASE.equals(location.toString())) { + return osgiArea; + } + return URIUtil.makeAbsolute(location, osgiArea); + } + + /* + * Return the attribute with the given name, or null if it does not exist. + */ + private static String getAttribute(Node node, String name) { + NamedNodeMap attributes = node.getAttributes(); + Node temp = attributes.getNamedItem(name); + return temp == null ? null : temp.getNodeValue(); + } + + /* + * Load the given file into a DOM document. + */ + @SuppressWarnings("restriction") + private static Document load(InputStream input) throws ParserConfigurationException, IOException, SAXException { + DocumentBuilderFactory factory = org.eclipse.core.internal.runtime.XmlProcessorFactory + .createDocumentBuilderFactoryWithErrorOnDOCTYPE(); + DocumentBuilder builder = factory.newDocumentBuilder(); + try (InputStream buffered = new BufferedInputStream(input)) { + return builder.parse(buffered); + } + } + + private Configuration internalParse(File file) { + if (!file.exists()) { + return null; + } + try (InputStream input = new FileInputStream(file)) { + Configuration result = process(load(input)); + if (result != null) { + result.setOsgiInstallArea(osgiInstallArea); + } + return result; + } catch (IOException | ParserConfigurationException | SAXException e) { + ILog.of(ConfigurationParser.class).error("Failed to read " + file, e); //$NON-NLS-1$ + return null; + } + } + + /* + * Process the given DOM document and create the appropriate site objects. + */ + private Configuration process(Document document) { + Node node = getConfigElement(document); + if (node == null) { + return null; + } + Configuration configuration = createConfiguration(node); + NodeList children = node.getChildNodes(); + int size = children.getLength(); + for (int i = 0; i < size; i++) { + Node child = children.item(i); + if (child.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + if (!ELEMENT_SITE.equalsIgnoreCase(child.getNodeName())) { + continue; + } + Site site = createSite(child); + if (site != null) { + configuration.add(site); + } + } + return configuration; + } + + private static Configuration createConfiguration(Node node) { + Configuration result = new Configuration(); + String value = getAttribute(node, ATTRIBUTE_SHARED_UR); + if (value != null) { + result.setSharedUR(value); + } + return result; + } + + private static Node getConfigElement(Document doc) { + NodeList children = doc.getChildNodes(); + int size = children.getLength(); + for (int i = 0; i < size; i++) { + Node child = children.item(i); + if (child.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + if (ELEMENT_CONFIG.equalsIgnoreCase(child.getNodeName())) { + return child; + } + } + return null; + } +} diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/Feature.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/Feature.java new file mode 100644 index 00000000000..222cf79a969 --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/Feature.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2005, 2008 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime.bundlegroups.platformxml; + +/* + * Represents a feature entry in a platform.xml file. + */ +public class Feature { + + private String id; + private String url; + private String version; + private String pluginIdentifier; + private String pluginVersion; + + public String getId() { + return id; + } + + public String getPluginIdentifier() { + return pluginIdentifier; + } + + public String getPluginVersion() { + return pluginVersion; + } + + public String getUrl() { + return url; + } + + public String getVersion() { + return version; + } + + public void setId(String id) { + this.id = id; + } + + public void setPluginIdentifier(String pluginIdentifier) { + this.pluginIdentifier = pluginIdentifier; + } + + public void setPluginVersion(String pluginVersion) { + this.pluginVersion = pluginVersion; + } + + public void setUrl(String url) { + this.url = url; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/Site.java b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/Site.java new file mode 100644 index 00000000000..8348e99a4dc --- /dev/null +++ b/runtime/bundles/org.eclipse.core.runtime.bundlegroups/src/org/eclipse/core/internal/runtime/bundlegroups/platformxml/Site.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.core.internal.runtime.bundlegroups.platformxml; + +import java.util.ArrayList; +import java.util.List; + +/* + * Represents a site in a platform.xml file. + */ +public class Site { + + private String url; + private final List features = new ArrayList<>(); + + public void addFeature(Feature feature) { + this.features.add(feature); + } + + public List getFeatures() { + return features; + } + + /** + * Note the string that we are returning is an ENCODED URI string. + */ + public String getUrl() { + return url; + } + + /** + * Note that the string should be an ENCODED URI string. + */ + public void setUrl(String url) { + this.url = url; + } +} diff --git a/update/org.eclipse.update.configurator.tests/src/org/eclipse/update/configurator/tests/AutomatedConfiguratorSuite.java b/update/org.eclipse.update.configurator.tests/src/org/eclipse/update/configurator/tests/AutomatedConfiguratorSuite.java index 6c6e2cbaf54..4dbe8d282a3 100644 --- a/update/org.eclipse.update.configurator.tests/src/org/eclipse/update/configurator/tests/AutomatedConfiguratorSuite.java +++ b/update/org.eclipse.update.configurator.tests/src/org/eclipse/update/configurator/tests/AutomatedConfiguratorSuite.java @@ -13,7 +13,6 @@ *******************************************************************************/ package org.eclipse.update.configurator.tests; -import org.eclipse.update.internal.configurator.tests.FeatureEntryTests; import org.eclipse.update.internal.configurator.tests.SiteEntryTests; import org.junit.platform.suite.api.SelectClasses; import org.junit.platform.suite.api.Suite; @@ -25,7 +24,6 @@ */ @Suite @SelectClasses({ // - FeatureEntryTests.class, // SiteEntryTests.class, // }) public class AutomatedConfiguratorSuite { diff --git a/update/org.eclipse.update.configurator.tests/src/org/eclipse/update/internal/configurator/tests/FeatureEntryTests.java b/update/org.eclipse.update.configurator.tests/src/org/eclipse/update/internal/configurator/tests/FeatureEntryTests.java deleted file mode 100644 index 8072cf4543a..00000000000 --- a/update/org.eclipse.update.configurator.tests/src/org/eclipse/update/internal/configurator/tests/FeatureEntryTests.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2019, 2020 Torbjörn Svensson and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Torbjörn Svensson - initial API and implementation - *******************************************************************************/ -package org.eclipse.update.internal.configurator.tests; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.net.MalformedURLException; -import java.net.URL; - -import org.eclipse.update.internal.configurator.FeatureEntry; -import org.eclipse.update.internal.configurator.SiteEntry; -import org.junit.jupiter.api.Test; - -@SuppressWarnings("restriction") -public class FeatureEntryTests { - - @Test - public void testLicenseUrl() throws MalformedURLException { - FeatureEntry featureEntry = new FeatureEntry("org.eclipse.platform", "4.13.0.v20190916-1323", null, null, false, null, null); - featureEntry.setSite(new SiteEntry(new URL("platform:/base/"))); - featureEntry.setURL("features/org.eclipse.platform_4.13.0.v20190916-1323/"); - - featureEntry.setLicenseURL("http://www.example.org"); - assertEquals("http://www.example.org", featureEntry.getLicenseURL()); - - featureEntry.setLicenseURL("https://www.example.org"); - assertEquals("https://www.example.org", featureEntry.getLicenseURL()); - - featureEntry.setLicenseURL("license.html"); - assertEquals("platform:/base/features/org.eclipse.platform_4.13.0.v20190916-1323/license.html", featureEntry.getLicenseURL()); - } -} \ No newline at end of file diff --git a/update/org.eclipse.update.configurator/META-INF/MANIFEST.MF b/update/org.eclipse.update.configurator/META-INF/MANIFEST.MF index a4f3934ac99..d28d69b429b 100644 --- a/update/org.eclipse.update.configurator/META-INF/MANIFEST.MF +++ b/update/org.eclipse.update.configurator/META-INF/MANIFEST.MF @@ -7,8 +7,7 @@ Bundle-Activator: org.eclipse.update.internal.configurator.ConfigurationActivato Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.update.configurator, - org.eclipse.update.internal.configurator;x-friends:="org.eclipse.update.core", - org.eclipse.update.internal.configurator.branding;x-friends:="org.eclipse.update.core" + org.eclipse.update.internal.configurator;x-friends:="org.eclipse.update.core" Require-Bundle: org.eclipse.core.runtime;bundle-version="3.29.0" Bundle-RequiredExecutionEnvironment: JavaSE-17 Import-Package: javax.xml.parsers, @@ -17,5 +16,4 @@ Import-Package: javax.xml.parsers, org.xml.sax.helpers Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.eclipse.update.configurator -Service-Component: OSGI-INF/org.eclipse.update.internal.configurator.BundleGroupComponent.xml, - OSGI-INF/org.eclipse.update.internal.configurator.PlatformConfigurationFactory.xml +Service-Component: OSGI-INF/org.eclipse.update.internal.configurator.PlatformConfigurationFactory.xml diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/BundleGroupComponent.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/BundleGroupComponent.java deleted file mode 100644 index 113d20ce3ad..00000000000 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/BundleGroupComponent.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2017 IBM Corporation and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.update.internal.configurator; - -import java.util.ArrayList; - -import org.eclipse.core.runtime.IBundleGroup; -import org.eclipse.core.runtime.IBundleGroupProvider; -import org.osgi.service.component.annotations.Activate; -import org.osgi.service.component.annotations.Component; -import org.osgi.service.component.annotations.Reference; - -/** - * Declarative services component that provides an implementation of - * {@link IBundleGroupProvider}. This allows the bundle group provider to be - * made available in the service registry before this bundle has started. - */ -@Component(service = IBundleGroupProvider.class) -@SuppressWarnings("removal") -public class BundleGroupComponent implements IBundleGroupProvider { - - - private final org.eclipse.update.configurator.IPlatformConfigurationFactory factory; - - @Activate - public BundleGroupComponent(@Reference org.eclipse.update.configurator.IPlatformConfigurationFactory factory) { - this.factory = factory; - } - - @Override - public IBundleGroup[] getBundleGroups() { - org.eclipse.update.configurator.IPlatformConfiguration configuration = factory - .getCurrentPlatformConfiguration(); - if (configuration == null) { - return new IBundleGroup[0]; - } - org.eclipse.update.configurator.IPlatformConfiguration.IFeatureEntry[] features = configuration - .getConfiguredFeatureEntries(); - ArrayList bundleGroups = new ArrayList<>(features.length); - for (org.eclipse.update.configurator.IPlatformConfiguration.IFeatureEntry feature : features) { - if (feature instanceof FeatureEntry && ((FeatureEntry) feature).hasBranding()) { - bundleGroups.add((IBundleGroup) feature); - } - } - return bundleGroups.toArray(new IBundleGroup[bundleGroups.size()]); - } - - @Override - public String getName() { - return Messages.BundleGroupProvider; - } - -} diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FeatureEntry.java b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FeatureEntry.java index 80806881707..6a568fdbf50 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FeatureEntry.java +++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/FeatureEntry.java @@ -13,20 +13,10 @@ *******************************************************************************/ package org.eclipse.update.internal.configurator; -import java.net.MalformedURLException; import java.net.URL; -import java.net.URLClassLoader; import java.util.ArrayList; -import java.util.MissingResourceException; -import java.util.ResourceBundle; -import org.eclipse.core.runtime.IBundleGroup; -import org.eclipse.core.runtime.Platform; import org.eclipse.update.configurator.IPlatformConfiguration; -import org.eclipse.update.internal.configurator.branding.AboutInfo; -import org.eclipse.update.internal.configurator.branding.IBundleGroupConstants; -import org.eclipse.update.internal.configurator.branding.IProductConstants; -import org.osgi.framework.Bundle; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -35,13 +25,7 @@ * * Feature information */ -public class FeatureEntry - implements - IPlatformConfiguration.IFeatureEntry, - IConfigurationConstants, - IBundleGroup, - IBundleGroupConstants, - IProductConstants { +public class FeatureEntry implements IPlatformConfiguration.IFeatureEntry, IConfigurationConstants { private final String id; private final String version; private final String pluginVersion; @@ -50,12 +34,8 @@ public class FeatureEntry private final boolean primary; private final String pluginIdentifier; private String url; - private String description; - private String licenseURL; private ArrayList plugins; - private AboutInfo branding; private SiteEntry site; - private ResourceBundle resourceBundle; private boolean fullyParsed; public FeatureEntry(String id, String version, String pluginIdentifier, String pluginVersion, boolean primary, String application, URL[] root) { @@ -190,112 +170,6 @@ public Element toXML(Document doc) { return featureElement; } - public void setDescription(String description) { - this.description = description; - } - - @Override - public Bundle[] getBundles() { - if (plugins == null) { - fullParse(); - } - - ArrayList bundles = new ArrayList<>(plugins.size()); - for (PluginEntry plugin : plugins) { - // get the highest version for the plugin - Bundle bundle = Platform.getBundle(plugin.getPluginIdentifier()); - if (bundle != null) { - bundles.add(bundle); - } - } - return bundles.toArray(new Bundle[bundles.size()]); - } - - @Override - public String getDescription() { - if (description == null) { - fullParse(); - } - return description; - } - - @Override - public String getIdentifier() { - return id; - } - - @Override - public String getName() { - if (branding == null) { - branding = AboutInfo.readFeatureInfo(id, version, getFeaturePluginIdentifier()); - } - return branding.getProductName(); - } - - @Override - public String getProperty(String key) { - if (key == null) { - return null; - } - - if (branding == null) { - branding = AboutInfo.readFeatureInfo(id, version, getFeaturePluginIdentifier()); - } - - // IBundleGroupConstants - if (key.equals(FEATURE_IMAGE)) { - return branding.getFeatureImageURL() == null ? null : branding.getFeatureImageURL().toExternalForm(); - } else if (key.equals(TIPS_AND_TRICKS_HREF)) { - return branding.getTipsAndTricksHref(); - } else if (key.equals(IBundleGroupConstants.WELCOME_PAGE)) { // same value is used by product and bundle group - return branding.getWelcomePageURL() == null ? null : branding.getWelcomePageURL().toExternalForm(); - } else if (key.equals(WELCOME_PERSPECTIVE)) { - return branding.getWelcomePerspectiveId(); - } else if (key.equals(BRANDING_BUNDLE_ID)) { - return pluginIdentifier; - } else if (key.equals(BRANDING_BUNDLE_VERSION)) { - return pluginVersion; - } else if (key.equals(APP_NAME)) { - return branding.getAppName(); - } else if (key.equals(ABOUT_TEXT)) { - return branding.getAboutText(); - } else if (key.equals(ABOUT_IMAGE)) { - return branding.getAboutImageURL() == null ? null : branding.getAboutImageURL().toExternalForm(); - } else if (key.equals(WINDOW_IMAGE)) { - return branding.getWindowImageURL()== null ? null : branding.getWindowImageURL().toExternalForm(); - } else if (key.equals(WINDOW_IMAGES)) { - URL[] urls = branding.getWindowImagesURLs(); - if (urls == null) { - return null; - } - StringBuilder windowImagesURLs = new StringBuilder(); - for (int i=0; i - * For example, assume resource bundle plugin.properties contains - * name = Project Name - *

- *
-	 *     resolveNLString(b,"Hello World") returns "Hello World"
-	 *     resolveNLString(b,"%name") returns "Project Name"
-	 *     resolveNLString(b,"%name Hello World") returns "Project Name"
-	 *     resolveNLString(b,"%abcd Hello World") returns "Hello World"
-	 *     resolveNLString(b,"%abcd") returns "%abcd"
-	 *     resolveNLString(b,"%%name") returns "%name"
-	 * 
- * - * @param resourceBundle resource bundle. - * @param string translatable string from model - * @return string, or null - * @since 2.0 - */ - public static String getResourceString(ResourceBundle resourceBundle, String string) { - - if (string == null) { - return null; - } - - String s = string.trim(); - - if (s.isEmpty()) { - return string; - } - - if (!s.startsWith(KEY_PREFIX)) { - return string; - } - - if (s.startsWith(KEY_DOUBLE_PREFIX)) { - return s.substring(1); - } - - int ix = s.indexOf(" "); //$NON-NLS-1$ - String key = ix == -1 ? s : s.substring(0, ix); - String dflt = ix == -1 ? s : s.substring(ix + 1); - - if (resourceBundle == null) { - return dflt; - } - - try { - return resourceBundle.getString(key.substring(1)); - } catch (MissingResourceException e) { - return dflt; - } - } public static boolean isAutomaticallyStartedBundle(String bundleURL) { if (bundleURL.contains("org.eclipse.osgi")) { //$NON-NLS-1$ diff --git a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/messages.properties b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/messages.properties index 0b2f4c3af9b..1d0bca48acc 100644 --- a/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/messages.properties +++ b/update/org.eclipse.update.configurator/src/org/eclipse/update/internal/configurator/messages.properties @@ -27,16 +27,10 @@ BundleManifest_noVersion = {0} attribute not found in manifest for bundle \"{1}\ FeatureParser_IdOrVersionInvalid= Error parsing feature stream. The unique identifier or the version is null or empty: unique identifier=\"{0}\" version=\"{1}\". -BundleGroupProvider=Update Manager Configurator ConfigurationParser_cannotLoadSharedInstall=Could not load from shared install PluginEntry_versionError=Unable to create versioned identifier: {0} {1} -IniFileReader_MissingDesc = Cannot find plugin for feature {0} -IniFileReader_OpenINIError = Cannot open branding file {0} -IniFileReader_ReadIniError = Error reading branding file {0} -IniFileReader_ReadPropError = Error reading branding properties file {0} -IniFileReader_ReadMapError = Error reading mapping files {0} SiteEntry_computePluginStamp = Cannot compute plugins change stamp for site {0} because it does not support plugin detection. SiteEntry_cannotFindFeatureInDir=Unable to find feature.xml in directory: {0}