Add a property on sonarqube using PropertyDefinition - plugins

I have a plugin with some properties defined with Property class but I want to reorder them so I used PropertyDefinition class. The problem is that in the Property class there is a "project" field but not in PropertyDefinition. And when I run it with PropertyDefinition, there are 0 settings.
Here is the previous code:
#Properties({
#Property(key = TestLinkPlugin.AAA, defaultValue = "false", name = "aa", description = "aa", project = true, type = PropertyType.BOOLEAN),...})
#Override
public void define(Context context) {
context.addExtensions(getExtensions());
}
And the new code:
#Override
public void define(Context context) {
context.addExtension(
PropertyDefinition.builder(TestLinkPlugin.AAA)
.name("aa")
.description("aa")
.defaultValue("false")
.type(PropertyType.BOOLEAN)
.index(0)
.build()
);
...
}
Thank you in advance for your help

I have found the soltuion, add this :
.onQualifiers(Qualifiers.PROJECT)

Related

Liferay create a custom PanelCategory for multiple portlet

I use Liferay 7.2 and Liferay IDE (eclipse). I created two separate Liferay admin portlet to creating a view for the database entries. I added in the first portlet "Teachers" a new panel called school with this generated code in application.list Package.
here is the code of - PanelApp.java
#Component(
immediate = true,
property = {
"panel.app.order:Integer=300",
"panel.category.key=" + TeachersPanelCategoryKeys.CONTROL_PANEL_CATEGORY
},
service = PanelApp.class
)
public class TeachersPanelApp extends BasePanelApp {
#Override
public String getPortletId() {
return TeachersPortletKeys.TEACHERS;
}
#Override
#Reference(
target = "(javax.portlet.name=" + TeachersPortletKeys.TEACHERS+ ")",
unbind = "-"
)
public void setPortlet(Portlet portlet) {
super.setPortlet(portlet);
}
}
.
public class TeachersPanelCategoryKeys {
public static final String CONTROL_PANEL_CATEGORY = "Teachers";
}
And here is the code of - PanelCategory.java
#Component(
immediate = true,
property = {
"panel.category.key=" + PanelCategoryKeys.SITE_ADMINISTRATION,
"panel.category.order:Integer=300"
},
service = PanelCategory.class)
public class TeachersPanelCategory extends BasePanelCategory {
#Override
public String getKey() {
return TeachersPanelCategoryKeys.CONTROL_PANEL_CATEGORY;
}
#Override
public String getLabel(Locale locale) {
return LanguageUtil.get(locale, "School");
}}
And here is the code of portlet.java
#Component(
immediate = true,
property = {
"com.liferay.portlet.add-default-resource=true",
"com.liferay.portlet.display-category=category.hidden",
"com.liferay.portlet.header-portlet-css=/css/main.css",
"com.liferay.portlet.layout-cacheable=true",
"com.liferay.portlet.private-request-attributes=false",
"com.liferay.portlet.private-session-attributes=false",
"com.liferay.portlet.render-weight=50",
"com.liferay.portlet.use-default-template=true",
"javax.portlet.display-name=Teachers",
"javax.portlet.expiration-cache=0",
"javax.portlet.init-param.template-path=/",
"javax.portlet.init-param.view-template=/view.jsp",
"javax.portlet.name=" + TeachersPortletKeys.TEACHERS,
"javax.portlet.resource-bundle=content.Language",
"javax.portlet.security-role-ref=power-user,user",
},
service = Portlet.class
)
public class TeachersPortlet extends MVCPortlet {
// some code to get entries from db
#Override
public void doView(final RenderRequest renderRequest, final RenderResponse renderResponse)
throws IOException, PortletException {
// some code
Now I want to add the second created portlet "Students" under the same Panel "School". I created it in the same way as "Teachers" but now I have two school panel. As it is shown in the image below.
I just want to display one panel category called school that contain both Teachers and Students in the list.
I do not know how I can think to do that.
As you're implementing a TeachersPanelCategory, I'm assuming you're also implementing a StudentsPanelCategory. From a naming perspective, I'd have expected a SchoolPanelCategory.
I'm currently at a loss of how the ControlPanel portlets actually declare their associated panel, but that place would be where you pick the common "school" panel and use the same spelling for both.
In other words: If you deploy two panels with the same name, I'd expect exactly what you document here. Make sure you're only deploying one of them
Edit: I'd like to know what TeachersPanelCategoryKeys.CONTROL_PANEL_CATEGORY is defined as, and the corresponding (assumed, not shown) StudentsPanelCategoryKeys.CONTROL_PANEL_CATEGORY. Both categories have the same label, but if they have different keys, they'll be different. I'm not sure what happens when you deploy two components with the same key: You should deploy only one.
Edit2: I've missed the code before: You're producing the key to your first category as "Teachers", and the label as "School". I'm assuming that the key for your other category is "Students". Liferay organizes the categories by key - and if the keys are different, then you'll end up with two different categories. Make their key more similar to their name (e.g. create a single SchoolCategory and associate your portlets/panelApps with that:
#Component(
immediate = true,
property = {
"panel.category.key=" + PanelCategoryKeys.SITE_ADMINISTRATION,
"panel.category.order:Integer=300"
},
service = PanelCategory.class)
public class SchoolPanelCategory extends BasePanelCategory {
#Override
public String getKey() {
return "school"; // this is the category that you want to associate with
}
#Override
public String getLabel(Locale locale) {
return LanguageUtil.get(locale, "School");
}
}
and
#Component(
immediate = true,
property = {
"panel.app.order:Integer=300",
"panel.category.key=school" // referencing the category created above
// (use the same for your StudentsPanelApp)
},
service = PanelApp.class
)
public class TeachersPanelApp extends BasePanelApp {
#Override
public String getPortletId() {
return TeachersPortletKeys.TEACHERS;
}
#Override
#Reference(
target = "(javax.portlet.name=" + TeachersPortletKeys.TEACHERS+ ")",
unbind = "-"
)
public void setPortlet(Portlet portlet) {
super.setPortlet(portlet);
}
}
(See the one-line comments within the code for the critical lines. Replace with proper constants if you like)

propertyChange not called when restoring default values

I am building a preference page extending the FieldEditorPreferencePage class.
This is the code (some obvious code not displayed):
public class PreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
public static final String PREF_KEY_1 = "checkBoxPref";
public static final String PREF_KEY_2 = "filePref";
private FileFieldEditor pathField;
private BooleanFieldEditor yesOrNoField;
private Composite pathFieldParent;
#Override
public void init(IWorkbench workbench) {
setPreferenceStore(new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID));
}
#Override
protected void createFieldEditors() {
this.yesOrNoField = new BooleanFieldEditor(PREF_KEY_1, "Check this box!", getFieldEditorParent());
this.pathFieldParent = getFieldEditorParent();
this.pathField = new FileFieldEditor(PREF_KEY_2, "Path:", this.pathFieldParent);
addField(this.yesOrNoField);
addField(this.pathField);
boolean isChecked = getPreferenceStore().getBoolean(PREF_KEY_1);
updatePathFieldEnablement(! isChecked);
}
/**
* Updates the fields according to entered values
*/
private void updatePathFieldEnablement(boolean enabled) {
this.pathField.setEnabled(enabled, this.pathFieldParent);
}
#SuppressWarnings("boxing")
#Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(FieldEditor.VALUE) && event.getSource() == this.yesOrNoField) {
updatePathFieldEnablement(! (boolean) event.getNewValue());
}
super.propertyChange(event);
}
}
The propertyChange method is there to enable/disable the FileFieldEditor depending on the BooleanFieldEditor value.
It works OK if I change the BooleanFieldEditor valeu by checking or unchecking it, but the propertyChange is not called when I hit the "Restore default values" button.
Do someone see a reason for that?
OK, I think I've got my response.
I went further in my investigation and I got to this code which seems suspect to me:
In class BooleanFieldEditor :
#Override
protected void doLoadDefault() {
if (checkBox != null) {
boolean value = getPreferenceStore().getDefaultBoolean(getPreferenceName());
checkBox.setSelection(value);
wasSelected = value;
}
}
and in class StringFieldEditor
#Override
protected void doLoadDefault() {
if (textField != null) {
String value = getPreferenceStore().getDefaultString(
getPreferenceName());
textField.setText(value);
}
valueChanged();
}
We can see that the FileFieldEditor (that inherits from StringFieldEditor) launches an PropertyChangeEvent to its listeners (valueChanged();) but not the BooleanFieldEditor. I did not find any code indicating that BooleanFieldEditor are using another mechanism. I think this is a bug in jFace.
To get around this problem, I just had to override the FieldEditorPreferencePage#performDefaults method and the result's fine.

Add my own rules in SonarQube with RPG

I want to create my own SonarQube Plugin for the RPG language. I have the following problem.
I start by created the RpgLanguage class that extends to AbstractLanguage. In this class, I defined my new language "Rpg". You can see my class in the following code :
public class RpgLanguage extends AbstractLanguage{
public static final String KEY = "rpg";
private Settings settings;
public RpgLanguage(Settings settings) {
super(KEY, "Rpg");
this.settings = settings;
}
public String[] getFileSuffixes() {
String[] suffixes = settings.getStringArray("");
if (suffixes == null || suffixes.length == 0) {
suffixes = StringUtils.split(".RPG", ",");
}
return suffixes;
}
}
After, I have created my RpgRulesDefinition class that implements RulesDefinition. In this class, I create a new repository for the language RPG and I want to add a rule in this repository (empty rules). The code is like below :
public static final String REPOSITORY_KEY = "rpg_repository_mkoza";
public void define(Context context) {
NewRepository repo = context.createRepository(REPOSITORY_KEY, "rpg");
repo.setName("Mkoza Analyser rules RPG");
// We could use a XML or JSON file to load all rule metadata, but
// we prefer use annotations in order to have all information in a single place
RulesDefinitionAnnotationLoader annotationLoader = new RulesDefinitionAnnotationLoader();
annotationLoader.load(repo, RpgFileCheckRegistrar.checkClasses());
repo.done();
}
My class RpgFileCheckRegistrar that call my Rules :
/**
* Register the classes that will be used to instantiate checks during analysis.
*/
public void register(RegistrarContext registrarContext) {
// Call to registerClassesForRepository to associate the classes with the correct repository key
registrarContext.registerClassesForRepository(RpgRulesDefinition.REPOSITORY_KEY, Arrays.asList(checkClasses()), Arrays.asList(testCheckClasses()));
}
/**
* Lists all the checks provided by the plugin
*/
public static Class<? extends JavaCheck>[] checkClasses() {
return new Class[] {
RulesExampleCheck.class
};
}
/**
* Lists all the test checks provided by the plugin
*/
public static Class<? extends JavaCheck>[] testCheckClasses() {
return new Class[] {};
}
My Rule class (still empty):
#Rule(
key = "Rule1",
name = "Rule that make nothing",
priority = Priority.MAJOR,
tags = {"example"}
)
public class RulesExampleCheck extends BaseTreeVisitor{
/**
* Right in java code your rule
*/
}
And the class SonarPlugin that call all these extensions :
public final class RpgSonarPlugin extends SonarPlugin
{
// This is where you're going to declare all your Sonar extensions
public List getExtensions() {
return Arrays.asList(
RpgLanguage.class,
RpgRulesDefinition.class,
RpgFileCheckRegistrar.class
);
}
}
The problem when I want to start the server sonar, I obtain this error stack :
Exception sending context initialized event to listener instance of class org.sonar.server.platform.PlatformServletContextListener
java.lang.IllegalStateException: One of HTML description or Markdown description must be defined for rule [repository=rpg_repository_mkoza, key=Rule1]
I try different things but I don't understand why there are these error.
Of course I want that my repository "rpg_repository_mkoza" is display in the RPG's repository in SonarQube with the Rules : RulesExampleCheck.
My sonar-plugin-version is the 3.7.1
I find my problem. There are need to add the field 'description' in #Rule.
For example :
#Rule(
key = "Rule1",
name = "RuleExampleCheck",
description = "This rule do nothing",
priority = Priority.INFO,
tags = {"try"}
)

GXT 3 GridRowEditing SimpleComboBox entries not displayed

i'm currently using a GXT3 grid to display data from a custom object EntityDAO.
This class contains 3 attributes: an id and two references to complex type objects
Let's call them
Long id;
UserInfo userInfo;
OutputInfo outputInfo;
I created an interface to explicit the desired display of these info:
interface EntityDAOProperties extends PropertyAccess<EntityDAO> {
ModelKeyProvider<EntityDAO> id();
#Path("userInfo.name")
ValueProvider<EntityDAO, String> step();
#Path("outputInfo.name")
ValueProvider<EntityDAO, String> outputInfo();
}
The display is perfectly fine. The matter is that i want to be able to add/edit rows to my grid.
To do so, I have a
GridRowEditing<EntityDAO> editing = createGridEditing(grid);
comprising a
SimpleComboBox<String> comboUser = new SimpleComboBox<String>(new LabelProvider<String>() {
#Override
public String getLabel(String item) {
return item;
}
});
for(...){
comboUser.add("entry " + i); // For instance
logger.info("entry : " +i); // For instance
i++;
}
comboUser.setEditable(false);
comboUser.setTriggerAction(TriggerAction.ALL);
When i double click on my line and make the GridRowEditing appear, the combo doesn't seem to have more than 1 row and the click on the expand arrow doesn't change anything to the matter.
I think you miss the part where you set the property editor for the combobox, here is the example code:
SimpleComboBox<Light> combo = new SimpleComboBox<Light>(new StringLabelProvider<Light>());
combo.setClearValueOnParseError(false);
combo.setPropertyEditor(new PropertyEditor<Light>() {
#Override
public Light parse(CharSequence text) throws ParseException {
return Light.parseString(text.toString());
}
#Override
public String render(Light object) {
return object == null ? Light.SUNNY.toString() : object.toString();
}
});
combo.setTriggerAction(TriggerAction.ALL);
combo.add(Light.SUNNY);
combo.add(Light.MOSTLYSUNNY);
combo.add(Light.SUNORSHADE);
combo.add(Light.MOSTLYSHADY);
combo.add(Light.SHADE);
// combo.setForceSelection(true);
editing.addEditor(cc2, new Converter<String, Light>() {
#Override
public String convertFieldValue(Light object) {
return object == null ? "" : object.toString();
}
#Override
public Light convertModelValue(String object) {
try {
return Light.parseString(object);
} catch (ParseException e) {
return null;
}
}
}, combo);
Hope this could help you.

showing image+text in suggestBox()

I am trying to display an icon along with text in suggestion drop down using SuggestBox and MultiWordSuggestOracle following code:
public class Suggestions implements Suggestion {
private String suggestion;
public Suggestions(){}
public Suggestions(String suggestion){
this.suggestion = new String( suggestion );
}
#Override
public String getDisplayString() {
return ( suggestion + " <img src='/images/image.png'/> " );
}
#Override
public String getReplacementString() {
return suggestion;
}}
And in onModuleLoad function contain following code:
MultiWordSuggestOracle oracle = new MultiWordSuggestOracle(){
#Override
public boolean isDisplayStringHTML() {
return true;
}};
oracle.add(new Suggestions("A").getDisplayString());
SuggestBox suggestionBox = new SuggestBox(oracle);
Problem : html code is printed as normal text. Could you guys please suggest whats wrong with the code?
Thanx!
Because your Suggestion class is never used !
The multiword oracle has just the display string, and create his own Suggestion items.
Just override the methode createSuggestion in the oracle :
MultiWordSuggestOracle oracle = new MultiWordSuggestOracle(){
#Override
public boolean isDisplayStringHTML() {
return true;
}
#Override
protected MultiWordSuggestion createSuggestion(String replacementString, String displayString) {
return new Suggestions(replacementString);
}
};
oracle.add(new Suggestions("A").getDisplayString());
SuggestBox suggestionBox = new SuggestBox(oracle);
Below is what I did to get image+text in suggestion drop down.
public class Suggestions implements Suggestion {
private String suggestion;
public Suggestions(){}
public Suggestions(String suggestion){
this.suggestion = new String( suggestion );
}
#Override
public String getDisplayString() {
return ( suggestion + new Image('/images/image.png') );
}
#Override
public String getReplacementString() {
return suggestion;
}}
OnModuleLoad function is:
MultiWordSuggestOracle oracle = new MultiWordSuggestOracle(){
#Override
public boolean isDisplayStringHTML() {
return true;
}
#Override
protected MultiWordSuggestion createSuggestion(String replacementString, String displayString) {
return new Suggestions(replacementString);
}
};
oracle.add("A");
SuggestBox suggestionBox = new SuggestBox(oracle);