I want to be able to inject a property based on a condition using SPRING.NET. Lets say I have two objects A and B and based on the value of a property that I evaluate in code I want to be able to inject A when it is true and inject B when the property value is false. Can I do that in spring.net?
<object id="Service" singleton="false" type="comp.Service, comp.Service">
// if(p1 == true) p1 is calculated in code.
<property name="_factory" ref="factory1" />
// else
<property name="_factory" ref="factory2" />
</object>
<object name="factory1" type="comp.Factory1, Factory1">
</object>
<object name="factory2" type="comp.Factory2, Factory2">
</object>
Yes you can. Use the expression:
<object id="Service" singleton="false" type="comp.Service, comp.Service">
<property name="_factory" expression="(p1 ? #(factory1) : #(factory2))" />
</object>
you may want to read documents about spring expression, it's a big topic.
Related
Is there any possibility to use extension function with a databinding?
XML:
<data>
<import type="my.package.domain.country.model.City.streetName" />
<variable
name="city"
type="my.package.domain.country.model.City" />
</data>
<TextView
android:id="#+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{city.street.streetName()}" />
my.package.domain.country.model.city
data class City(
val id: String,
val street: Street
)
fun City.streetName(): String = street.houseNumber
Error
[kapt] An exception occurred:
android.databinding.tool.util.LoggedErrorException: Found data binding
errors.
****/ data binding error ****msg:cannot find method streetName() in class my.package.domain.country.model.City
Thanks ;)
You have to import CityKt firstly into xml
<import type="my.package.domain.country.model.CityKt" />
int the data section
then you can use it like this
<TextView
android:id="#+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{CityKt.streetName(city)}" />
If you review CityKt you will see that there is static Java method with City as first argument
While #skiff2011 is correct, one could also use alias to prevent the Kt postfix.
For example, a certain extension function is located in ExtensionFunctionsKt can be aliased by ExtensionFunctions
<import
alias="ExtensionFunctions"
type="com.helloworld.app.util.ExtensionFunctionsKt" />
<variable
name="someData"
type="com.helloworld.app.model.SomeData" />
The ExtensionFunction alias can now be used to call the extension function. The first argument still needs to be the extended class variable.
<TextView
android:id="#+id/city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{ExtensionFunctions.doStuff(someData)}" />
Extension function
Ex:
fun Context.isDarkMode(): Boolean {
}
Now we have Extenstion function for dark mode which can be accessed using context.
Usually in Kotlin class we can access using context obj like below.
context.isDarkMode()
But in Xml,we can't access like above.
We need to import Extension function by appending KT to class.
Ex) If your file name is Extensions,then import should be ExtensionsKt.
Import like below in xml.
<import type="com.example.extensions.ExtensionsKt" />
And then we can access Extension function like below i.e we need to pass object for which we are creating Extension i.e in our case it is context.
app:context='#{(ExtensionsKt.isDarkMode(context)}'
If using Utils class you can to this:
object Utils(){
fun streetName(): String {}
}
<import
type="com.helloworld.app.util.Utils" />
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{Utils.INSTANCE.streetName()}"
/>
Use view model for to call extension functions.
I am trying to write an AppleScript that calls my Swift application to get a value. The method takes a string and needs to return another string.
Here is my .SDF file:
<suite name="My Suite" code="MySU" description="My AppleScript suite.">
<class name="application" code="capp" description="An application's top level scripting object.">
<cocoa class="NSApplication"/>
<element type="my types" access="r">
<cocoa key="types"/>
</element>
</class>
<command name="my command" code="MyCOMMND" description="My Command">
<parameter name="with" code="MyPR" description="my Parameter" type="text">
<cocoa key="myParameter"/>
</parameter>
<result type="text" description="the return value"/>
<cocoa method="myCommand:"/>
</command>
</suite>
The corresponding Swift code is fairly simple:
func myCommand(_ command: NSScriptCommand) -> String
{
if let myParameter = command.evaluatedArguments?["myParameter"] as? String
{
return "Hello World!"
}
else
{
return "Nothing happening here. Move on."
}
}
and finally my AppleScript is here:
tell application "MyApp"
set r to my command with "Hello"
end tell
When I execute the AppleScript it recognises my command, but it does not call the Swift code that I've tried to associate with it. Neither Xcode or AppleScript report a problem. Have I misses something out or put my code in the wrong place?
For this sort of scripting I would recommend a command-first (aka verb-first) approach rather than the object-first approach you are attempting. Your sdef would look like this (replacing "MyProject" with the name of your project, i.e. your application's Swift module name):
<dictionary xmlns:xi="http://www.w3.org/2003/XInclude">
<suite name="My Suite" code="MySU" description="My AppleScript suite.">
<command name="my command" code="MySUCMND" description="My Command">
<cocoa class="MyProject.MyCommand"/>
<parameter name="with" code="MyPR" description="my Parameter" type="text">
<cocoa key="myParameter"/>
</parameter>
<result type="text" description="the return value"/>
</command>
</suite>
</dictionary>
The MyCommand class should look like this:
class MyCommand : NSScriptCommand {
override func performDefaultImplementation() -> Any? {
if let _ = self.evaluatedArguments?["myParameter"] as? String
{
return "Hello World!"
}
else
{
return "Nothing happening here. Move on."
}
}
}
The "ModuleName.ClassName" sdef tip comes from Swift NSScriptCommand performDefaultImplementation
I implemented the tuple from here: https://voidnish.wordpress.com/2013/07/13/tuple-implementation-via-variadic-templates/
Is it possible to visualize it with NATVIS? I got as far as
<Type Name="tuple">
<DisplayString>()</DisplayString>
</Type>
<Type Name="tuple<*>">
<DisplayString>({_Myfirst})</DisplayString>
</Type>
How can I get the _Myfirst value for more than one type, to get
<Type Name="tuple<*,*>">
<DisplayString>({_Myfirst}, {???})</DisplayString>
</Type>
<Type Name="tuple<*,*,*>">
<DisplayString>({_Myfirst}, {???}, {???})</DisplayString>
</Type>
etc?
You'll have to modify the type a little to get this to work. What's required is a base_type typedef.
i.e.
// tuple
template<class... _Types> class tuple;
// empty tuple
template<> class tuple<> {};
// recursive tuple definition
template<class _This,
class... _Rest>
class tuple<_This, _Rest...>
: private tuple<_Rest...>
{
public:
typedef tuple<_Rest...> base_type; // ***** Added this line
_This _Myfirst;
};
Now we can recursively evaluate the base types with the natvis declarations:
<!-- Handle empty tuples -->
<Type Name="tuple<>">
<DisplayString>()</DisplayString>
<Expand/>
</Type>
<!-- Handle a single parameter (this is also our terminator for recursion) -->
<Type Name="tuple<*>">
<DisplayString IncludeView="noparens">{_Myfirst}</DisplayString>
<DisplayString ExcludeView="noparens">({_Myfirst})</DisplayString>
<Expand>
<Item Name="Value">_Myfirst</Item>
</Expand>
</Type>
<!-- Handle 2 or more items -->
<Type Name="tuple<*,*>">
<!-- show the first item and then recurse by casting this to 'base_type' -->
<DisplayString IncludeView="noparens">{_Myfirst}, {*(base_type *)this,view(noparens)}</DisplayString>
<!-- Wrap our display string that doesn't a have any parentheses, this will be only done for the top level tuple -->
<DisplayString ExcludeView="noparens">({*this,view(noparens)})</DisplayString>
<Expand>
<!-- Show the top level item -->
<Item Name="Value">_Myfirst</Item>
<!-- Recursively expand our base types -->
<ExpandedItem>*(base_type *)this</ExpandedItem>
</Expand>
</Type>
And this is the result:
How can i parse xml result to tableview with two lines per cell in Swift?
I want to show the result like this in a table view
TableView
================
userID: brat_peet
password: 12124521
================
userID: Miketyson
password: Miketyson
================
How can i do it?
Here is my xml result.
<Record table="User" partial="true">
<Field name="userID" primaryKey="true"><![CDATA[brat_peet]]></Field>
<Field name="password" primaryKey="true"><![CDATA[12124521]]></Field>
</Record>
<Record table="User" partial="true">
<Field name="userID" primaryKey="true"><![CDATA[Miketyson]]></Field>
<Field name="password" primaryKey="true"><![CDATA[Miketyson]]></Field>
</Record>
<Record table="User" partial="true">
<Field name="userID" primaryKey="true"><![CDATA[Kennedy]]></Field>
<Field name="password" primaryKey="true"><![CDATA[754123654]]></Field>
</Record>
</ATBResponse>
For the tableView:
"Two lines per cell" is an irrelevant value. You can use "custom" style cells and put in as many Text Labels (and images and whatever) you want inside each cell. So, to have two "lines" per cell you can simply choose "custom" cell, drag it down to increase the size and insert two Labels inside.
For the XML parsing:
First you have to understand how a XML is parsed in Swift. Here's a tutorial I wrote:
https://medium.com/#lucascerro/understanding-nsxmlparser-in-swift-xcode-6-3-1-7c96ff6c65bc
In your case, you have to construct your code so you only check the <Field> element when inside a <Record> element. Then you differentiate between "username" and "password" data by checking your <Field>'s attributes.
For the String:
Lastly, your resulting foundCharacters will not be the final data you need. There are many methods of the String type that can solve this. One example is to use the method removeRange to remove the starting and ending characters, since they appear to always be the same ones (in your case: "<![CDATA[" and "]]>", assuming you're getting them returned as String types).
I am using dynamic MenuContribution and get a warning that two of my referenced identifiers "cannot be found". Even though the contribution works. These warnings bug me.
I have a CompoundContributionItem implementation defined in one of my plugins. Basically it looks like this:
public class ViewerHistoryMenuItems extends CompoundContributionItem
implements IExecutableExtension {
private static final String PARAM_TYPE = "type";
private static final String PARAM_COMMAND = "command";
// some fields
public void setInitializationData(final IConfigurationElement config,
final String propertyName, final Object data) {
/* set fields */
}
protected final IContributionItem[] getContributionItems() {
/* create Items */
}
}
In other plugins I use this ContributionItem implementation by declaring the following:
<menuContribution locationURI="menu:mylocationUri">
<dynamic id="myId">
<class class="ViewerHistoryMenuItems">
<parameter
name="type"
value="someValue">
</parameter>
<parameter
name="command"
value="someCommandId">
</parameter>
</class>
</dynamic>
<command
commandId="someCommandId"
icon="anIcon.png">
</command>
</menuContribution>
When looking at the Problems-View I get two entries there (for each plug-in, which uses this contribution):
**Referenced identifier 'type' in attribute 'name' cannot be found**
**Referenced identifier 'command' in attribute 'name' cannot be found**
What am I missing here? Any ideas, why I get this warning?
PS: It doesn't help, to make the two fields PARAM_TYPE & PARAM_COMMAND public
I do not think this is related to the presence of internal fields within a class.
If you look at a similar error (not the same since it includes annotationType), the correction involved the definition of said Referenced identifier:
Referenced identifier 'com.atlassian.connector.eclipse.cruicible.ui.comment.annotation'
in attribute 'annotationType' cannot be found
Fixed with:
+ <extension
+ point="org.eclipse.ui.editors.annotationTypes">
+ <type
+ markerType="com.atlassian.connector.eclipse.crucible.ui.com.atlassian.connector.eclipse.cruicible.ui.comment.marker"
+ name="com.atlassian.connector.eclipse.cruicible.ui.comment.annotation">
+ </type>
+ </extension>
+ <extension
+ id="com.atlassian.connector.eclipse.cruicible.ui.comment.marker"
+ point="org.eclipse.core.resources.markers">
+ </extension>
Considering the extension point org.eclipse.ui.menus help page:
<!ELEMENT parameter EMPTY>
<!ATTLIST parameter
name IDREF #REQUIRED
value CDATA #REQUIRED
>
A parameter to either an executable extension or a command -- depending on where it appears in the extension.
name - The name is either the name of the parameter to pass to the executable extension, or the identifier of the parameter for the command.
value - The value to pass for this parameter.
You need to reference in the name attribute an id present somewhere else in your plugin.xml.
Sure thing, VonC. Here we go:
Within the dynamic declaration (see above) there are two parameter references
<parameter
name="type"
value="someValue">
</parameter>
<parameter
name="command"
value="someCommandId">
</parameter>
These two parameter are meant to be passed to the command itself. The command declaration is within the same plugin.xml but wasn't declaring these two commandParameters.
What I did was adding these missing commandParameters, resolving the missing reference, which was clearly stated by the warning.
<command
categoryId="aCategory"
id="someCommandId"
name="%theName">
<commandParameter
id="type"
name="type"/>
<commandParameter
id="command"
name="command">
</commandParameter>
</command>
So, you were absolutely right by saying "the correction involved the definition of said reference identifier". The question just was where and what I had to define.
I think, I wasn't thinking about the most obvious in this case.