How to convert string containing macro in wiki markup to xhtml format - confluence

During migration procedure from Confluence 3.5.13 to Confluence 5.0.3, I need in my MacroMigration class to convert a string containing some text and macro to xhtml format.
I've tried the following code:
WikiStyleRenderer wikiStyleRenderer = (WikiStyleRenderer) ContainerManager.getComponent("wikiStyleRenderer");
String result= wikiStyleRenderer.convertWikiToXHtml(new PageContext(context.getEntity()), body.getBody());
It works on simple text but as soon as it contains a reference to a macro (for example {info:title=int Random(int range)}{info}) the result is just an line feed ('\n').

I've succeeded to get it working using the com.atlassian.confluence.xhtml.api.XhtmlContent interface. Here is how I did:
private XhtmlContent xhtmlContent;
public void setXhtmlContent(XhtmlContent xhtmlContent) {
this.xhtmlContent = xhtmlContent;
}
public MacroDefinition migrate(MacroDefinition macroDefinition,
ConversionContext context) {
MacroBody body = macroDefinition.getBody();
List<RuntimeException> migrationExceptions = new ArrayList<RuntimeException>();
String resultContent;
resultContent = xhtmlContent.convertWikiToStorage(body.getBody(),
context, migrationExceptions);
The setter setXhtmlContent() is just there for Confluence to inject the right instance.

Related

IntelliSense/ReSharper and custom Quickfixn library generation

I am developing a Quickfix/n initiator to be used with several counterparties, in the same instance, all using the same version of FIX (4.2 in this instance) but utilizing a unique messaging specification and I would like to use Intellisense/ReSharper to develop said initiator.
Previously I have used the generate.rb script to create source code from a modified FIX##.xml file but would like to use something like FIX42.DeutcheBank.xml, FIX42.CME.xml, FIX42.Whatever, to generate the source with the generate.rb ruby script or a modified version thereof so they can be parsed by IntelliSense/ReSharper and I am having issues because they all use "FIX.4.2" as begin strings and thus causes a compile error.
I know that I can just refer to a field/group via a key like Tags["BidForwardPointsCME"] or something similar with a DataDictionary but, as stated, I would like to be able to use IntelliSense/ReSharper and reference the message fields/groups with something like Quickfix.CounterParty.WhateverField and using the same dll.
I've banged my head against the internet for answers for 3-4 days with no luck - Is what I would like to do possible? If so, how would one go about it?
Hi in advance to Grant Birchmeier <:-]
For anyone that ever is trying to do this, the answer is pretty simple - probably not the most efficient but it works as far as I know.
the trick is to edit two ruby generation scripts (messages_gen.rb and generate.rb) and place the additional FIX specification XML file(s) in the spec/fix directory.
Assuming that you have a custom FIX xml file for Foo Exchange and that the Foo Exchange uses FIX 4.2, you need to name it FIX.xml (Example: FIXFooExchange.xml)
Next, you will have to override the FIX version in messages_gen.rb like so:
def self.gen_basemsg fixver, destdir
beginstring = fixver
if beginstring.match(/^FIX50/)
beginstring = "FIXT11"
end
if beginstring.match(/^FIXFooExchange/)
beginstring = "FIX42"
end
Next you need to add your custom fix version to 6 method definitions in the generate.rb file.
Those methods are:
initialize
agg_fields
get_field_def
generate_messages
generate_csproj
generate_message_factories
Here are a few examples:
def initialize
#fix40 = FIXDictionary.load spec('FIX40')
#fix41 = FIXDictionary.load spec('FIX41')
#fix42 = FIXDictionary.load spec('FIX42')
#fix43 = FIXDictionary.load spec('FIX43')
#fix44 = FIXDictionary.load spec('FIX44')
#fix50 = FIXDictionary.load spec('FIX50')
#fix50sp1 = FIXDictionary.load spec('FIX50SP1')
#fix50sp2 = FIXDictionary.load spec('FIX50SP2')
#fixFooExchange = FIXDictionary.load spec('FIXFooExchange')
#src_path = File.join File.dirname(__FILE__), '..', 'QuickFIXn'
end
def get_field_def fld_name
# we give priority to latest fix version
fld = merge_field_defs(
#fix50sp2.fields[fld_name],
#fix50sp1.fields[fld_name],
#fix50.fields[fld_name],
#fix44.fields[fld_name],
#fixFooExchange.fields[fld_name],
#fix43.fields[fld_name],
#fix42.fields[fld_name],
#fix41.fields[fld_name],
#fix40.fields[fld_name]
)
End
Basically you just copy one line and replace the fix version with the customized exchange xml data dictionary name.
The class BeginString in FixValues.cs should be modified to look like this:
public class BeginString
{
public const string FIXT11 = "FIXT.1.1";
public const string FIX50 = "FIX.5.0";
public const string FIX44 = "FIX.4.4";
public const string FIX43 = "FIX.4.3";
public const string FIXFooExchange = "FIX.4.2";
public const string FIX42 = "FIX.4.2";
public const string FIX41 = "FIX.4.1";
public const string FIX40 = "FIX.4.0";
}
The Values.cs file contains a single class which should be changed to look like this:
public class Values
{
public const string BeginString_FIXT11 = "FIXT.1.1";
public const string BeginString_FIX50 = "FIX.5.0";
public const string BeginString_FIX44 = "FIX.4.4";
public const string BeginString_FIX43 = "FIX.4.3";
public const string BeginString_FIXFooExchange = "FIX.4.2";
public const string BeginString_FIX42 = "FIX.4.2";
public const string BeginString_FIX41 = "FIX.4.1";
public const string BeginString_FIX40 = "FIX.4.0";
}
Do those things and then run the generate.bat file and you should be able to reference namespaces via '.' rather than using the base FIX version.
Here are some examples:
using QuickFix.FIXFooExchange;
using Message = QuickFix.Message;
QuickFix.FIXFooExchange.MessageFactory mF = new QuickFix.FIXFooExchange.MessageFactory();
and reference message properties like:
string customField = message.yourCustomFieldName.getValue().ToUpper();
instead of by
string customField = message["yourCustomFieldName"].getValue().ToUpper();
Lastly, you need to edit 2 .cs files: FixValues.cs and Values.cs
I've tested this pretty extensively and it seems to work but I would advise that you do testing before you put anything in production.
So the problem is you want 1 QF initiator process to connect to several different counterparties where each session uses a separate data dictionary?
Don't you do this using DataDictionary=somewhere/FIX42.xml in the configuration file?
See also http://quickfixn.org/tutorial/configuration.html AppDataDictionary: This setting supports the possibility of a custom application data dictionary for each session.

Attach a CSV in Mail

I want to attach a csv file in mail(grails)
The file in the path is already present. I am using the following code
sendMail {
multipart true
from "$senderName <$fromAddress>"
to toAddress
cc message.cc
subject message.subject
body content.plaintext
html content.html
attachBytes './web-app/ReadyOrdersFor-${vendor.name}','text/csv', new File('./web-app/ReadyOrdersFor-${vendor.name}').readBytes()
}
Error prompted is.
java.io.FileNotFoundException: ./web-app/ReadyOrdersFor-${vendor.name}.csv (No such file or directory)
neither this works prompting the same error
attachBytes './web-app/ReadyOrdersFor-${vendor.name}.csv','text/csv', new File('./web-app/ReadyOrdersFor-${vendor.name}.csv').readBytes()
The issue is that you trying you use the file path string as a GStringImpl, but the string is enclosed in single quotes. GStringImpl is natively supported in groovy in double quotes.
You code should be
attachBytes "./web-app/ReadyOrdersFor-${vendor.name}",'text/csv', new File("./web-app/ReadyOrdersFor-${vendor.name}").readBytes()
This link should help you understand the difference between using single and double quotes in groovy.
Instead of trying to get a File reference using new File(path), use the Spring ResourceLoader interface. The ApplicationContext implements this interface, so you can get a reference to it from a controller (for example) like this:
class MyController implements ApplicationContextAware {
private ResourceLoader resourceLoader
void setApplicationContext(ApplicationContext applicationContext) {
resourceLoader = applicationContext
}
def someAction() {
String path = "classpath:/ReadyOrdersFor-${vendor.name}"
File csvFile = resourceLoader.getResource(path).file
}
}
I'm not 100% sure the path value above is correct, you may need to remove the '/'

Form fields are reset on validation error

I have a rather complex form in the way that the number of form fields is flexibel. In short, the model object is a TLabel (TranslationLabel) that contains a Map of values (translations). Language here is an enum so the idea is that the number of fields (text areas) for which a translation is given depends on the values in this enum.
This is my form (simplified):
public class TranslationEditForm extends Form {
private final static List<Language> LANGUAGES = newArrayList(Language.values());
public TranslationEditForm(String id, final TranslationLabelView label) {
super(id, new CompoundPropertyModel<TranslationLabelView>(label));
ListView<Language> textAreas = new ListView<Language>("translationRepeater", LANGUAGES) {
#Override
protected void populateItem(final ListItem<Language> itemLang) {
//loop through the languages and create 1 textarea per language
itemLang.add(new Label("language", itemLang.getModelObject().toString()));
Model<String> textModel = new Model<String>() {
#Override
public String getObject() {
//return the value for current language
return label.getValue(itemLang.getModelObject());
}
#Override
public void setObject(String object) {
//set the value for current language
label.getTranslations().put(itemLang.getModelObject(), object);
}
};
itemLang.add(new TextArea<String>("value", textModel).setRequired(true));
}
};
//add the repeater containing a textarea per language to the form
this.add(textAreas);
}
}
Now, it works fine, 1 text area is created per language and its value is also set nicely; even more when changed the model gets updated as intended.
If you submit the form after emptying a text area (so originally there was a value) then of course there is a validation error (required). Normal (wicket) behaviour would be that the invalid field is still empty but for some reason the original value is reset and I don't understand why.
If I override onError like this:
#Override
protected void onError() {
this.updateFormComponentModels();
}
then it is fine, the value of the field is set to the submitted value (empty) instead of the original value.
Any idea what is causing this? What is wicket failing to do because the way I've set up the form (because with a simple form/model this is working fine as are the wicket examples)?
Posted as answer, so the question can be marked as solved:
ListView does recreate all its items at render time. This means that the validation will be broken. Have a look at API doc of the ListView
Calling setReuseItems() on the ListView solves this.
Regards,
Bert

Turn links in wicket panels to hyperlinks

I'm trying to find a way to automatically convert links in a panel to hyper-links. So for example a user input is:
"And here you can find my awesome example: http://example.com"
Is it possible in wicket to add an anchor element to each "http://..." text, so the above example would output
"And here you can find my awesome example: http://example.com"
instead?
You can use Wicket's built in SmartLinkLabel.
From the Javadoc:
If you have email addresses or web URLs in the data that you are displaying, then you can automatically display those pieces of data as hyperlinks, you will not have to take any action to convert that data.
One way to do this is to extend Label and override onComponentTagBody
Something like:
public class AnchorizeLabel extends Label {
public AnchorizeLabel(String id, String body) {
super(id, body);
}
#Override
protected void onComponentTagBody(MarkupStream stream, ComponentTag tag) {
String newBody = createAnchors(getDefaultModelObjectAsString());
replaceComponentTagBody(stream, tag, newBody);
}
private String createAnchors(String body) {
// regex magic to create links
}
}
You can also accomplish this with a custom IModel or IConverter but I prefer the Label approach.

Is there a way to capitalize the first letter of a value of a variable in Eclipse (Helios) code templates

I have a code template with a variable and I would like to capitalize(just the first letter) the value of this variable only in some occurrences. Is there a way to do this?
The template code is as follows - I would like to capitalize Property Name in my function names...
private $$${PropertyName};
${cursor}
public function get${PropertyName}()
{
return $$this->${PropertyName};
}
public function set${PropertyName}($$value)
{
$$this->${PropertyName} = $$value;
}
Please Note: This is a template for use with code templates in the IDE (not in PHP). For details see: http://www.ibm.com/developerworks/opensource/tutorials/os-eclipse-code-templates/index.html
I also want this and tried to build a custom TemplateVariableResolver to do it. (I already have one custom resolver in place that generates new UUIDs a la http://dev.eclipse.org/blogs/jdtui/2007/12/04/text-templates-2/.)
I made a custom resolver bound to capitalize:
public class CapitalizingVariableResolver extends TemplateVariableResolver {
#Override
public void resolve(TemplateVariable variable, TemplateContext context) {
#SuppressWarnings("unchecked")
final List<String> params = variable.getVariableType().getParams();
if (params.isEmpty())
return;
final String currentValue = context.getVariable(params.get(0));
if (currentValue == null || currentValue.length() == 0)
return;
variable.setValue(currentValue.substring(0, 1).toUpperCase() + currentValue.substring(1));
}
}
(plugin.xml:)
<extension point="org.eclipse.ui.editors.templates">
<resolver
class="com.foo.CapitalizingVariableResolver"
contextTypeId="java"
description="Resolves to the value of the variable named by the first argument, but with its first letter capitalized."
name="capitalized"
type="capitalize">
</resolver>
</extension>
that I would use like this: (I am working in Java; I see that you do not appear to be)
public PropertyAccessor<${propertyType}> ${property:field}() {
return ${property};
}
public ${propertyType} get${capitalizedProperty:capitalize(property)}() {
return ${property}.get();
}
public void set${capitalizedProperty}(${propertyType} ${property}) {
this.${property}.set(${property});
}
As of Eclipse 3.5, the problem I am having is that my custom resolver does not get a chance to re-resolve once I've specified a value for the property variable. It appears that the Java Development Tools (Eclipse JDT) do this dependent template variable re-resolution via a mechanism called MultiVariableGuess within the JavaContext (see addDependency()). Unfortunately for us, that mechanism does not seem to be exposed, so I/we can't use it to do the same (without lots of copy-and-paste or other redundant work).
At this point, I am giving up again for a while and will keep typing the leading-lowercase and leading-uppercase names separately into two independent template variables.