In the example for the magnolia module configuration in the documentation I am not sure why the private boolean colorsEnabled;for the FooBar class is not in the YAML configuration. Where does the module configuration get the colorsEnabled property from?
maxSize: 25
welcomeMessage: Hello world
fooBar:
colors: [red, green, blue]
Also the when I programmatically retrieve the List<String> list = fooBar.getColors(); I get null for the list.
I am running Magnolia 5.7.9.
UPDATE:
My module class is done the same way as described in the documentation and the example described above.
public class XxxVersioning implements ModuleLifecycle {
private Excludes excludes;
public Excludes getExcludes() {
return excludes;
}
public void setExcludes(Excludes excludes) {
this.excludes = excludes;
}
public class Excludes {
private String red;
private String green;
public String getRed() {
return red;
}
public void setRed(String red) {
this.red = red;
}
public String getGreen() {
return green;
}
public void setGreen(String green) {
this.green = green;
}
}
I have a class that programmatically inquires if a string value is in the list. The the list appears to be null.
/**
* Find if template name for the component in the module exception list
* #param String templateName
* #return Boolean true if templateName in the module exception-list
*/
public Boolean isComponentException(String templateName) {
// get the (singleton) instance of the module
// On the module class instance call the getter methods of the module bean properties.
XxxVersioning moduleInstance = xxxVersionProvider.get();
// access the modules RenderingExcludes bean
XxxVersioning.Excludes excludes = moduleInstance.getExcludes();
String green = excludes.getGreen();
return true;
}
SOLUTION:
For bootstrapping I found the document [here][5] According to this document
All bootstrap files are only imported once!
Webapp-based bootstrap files are imported during the first run of the webapp when the Magnolia instance gets installed.
Module-based bootstrap files are imported during the installation of the module.
If you want to import bootstrap files on every start up of the Magnolia instance or of a module, you must use custom installation tasks which are executed by the Module version handler or Module start up classes.
FooBar class is not in the YAML configuration. Where does the module
configuration get the colorsEnabled property from?
First YAML/FS is checked, then from the JCR configuration (config workspace in the repo). Or if property of that name doesn't exist it would take the default value.
More on the order in which resources are checked here.
The list appears to be always null.
yes, because you override the value from yaml with the one in config workspace (or you have just one in the workspace and nothing in yaml?) and there you still write the property list in yaml format instead of using syntax appropriate for jcr (which would be contentNode called excludes with 4 properties under that node each being name/value pair representing the individual colors. Unfortunately documentation doesn't show how that differs so clearly so it's easy to make a mistake there.
Anyway, as a good practice you should choose where you will store your configuration - either in repo or in yaml. I would suggest yaml config in FS as it allows you to change the configuration from outside even if your app gets corrupted. Plus it's easier to keep that file in git or other VCS and have proper history of changes on it tracked.
Related
The title says it all ...
In Sandcastle Help File Builder we added the NamespaceDoc class to each namespace to create namespace documentation.
How do we to the same using DocFX?
Here's how I did it:
In the root folder of your documentation project, add a folder named namespaces.
Update your docfx.json file to include markup files added to the namespaces folder. You need to update the overwrite property in the build section. It will look something like this:
"overwrite": [
{
"files": [
"apidoc/**.md",
"namespaces/**.md"
],
"exclude": [
"obj/**",
"_site/**"
]
}
],
Create a markdown file in the namespaces folder for every namespace you want to add documentation to. It is probably best to name these files the same as the namespace.
The files should have a YAML header with a UID that matches the namespace's name. The summary: *content line tells docfx to overwrite the summary of the namespace with the contents of this file.
The rest of the page is standard markdown that will become the namespace's summary. For example:
---
uid: My.Groovy.Namespace
summary: *content
---
The My.Groovy.Namespace namespace contains a bunch of classes and interfaces.
There isn't a way to add it directly in source code. You can use overwrite files to add summary for namespace type.
I'm probably extremely late to this question, but i faced a similar problem and the solution i found invovles modifying docfx from source and adding helping classes, much like Sandcastle's solution.
Disclamer:
I do not claim that the solution i'm showcasing is programmatically
stable, safe or even correct. I do not claim that this solution will
work in any scenario or for any use. I only verify that, for me, it
worked perfectly fine, even though i recongize it's just a fast-put-up
workaround.
Steps :
I downloaded the source code of docfx from their github's releases page (2.59.2, as of today)
After extracting the solution, I opened the file docfx-2.59.2\src\Microsoft.DocAsCode.Metadata.ManagedReference\ExtractMetadataWorker.cs
The class implemented within this file contains a method named GetMetadataFromProjectLevelCache that, at some point, extracts the metadata
from the referenced project in a tree form.
private Tuple<MetadataItem, bool> GetMetadataFromProjectLevelCache(IBuildController controller, IInputParameters key){
// [...]
projectMetadata = controller.ExtractMetadata(key); // THIS line
// [...]
}
After this line, I appended the following line containing a method which I also had to implement.
private Tuple<MetadataItem, bool> GetMetadataFromProjectLevelCache(IBuildController controller, IInputParameters key){
// [...]
projectMetadata = controller.ExtractMetadata(key);
ExtractNamespaceDocumentation(projectMetadata); // THIS line
// [...]
}
The implementation was the following:
private void ExtractNamespaceDocumentation(MetadataItem node)
{
// Terminal nodes are not of our interest in any case
// Even if it's a namespace, it does not contain documentation
if (node.Items is not { Count: > 0 }) return;
// If it is namespace
if (node.Type == MemberType.Namespace)
{
// Get (if any), the child that is class and is named "_NamespaceDoc"
var doc = node.Items.FirstOrDefault(x =>
x.Type == MemberType.Class && x.Name.Split('.').Last() == "_NamespaceDoc");
// If we didn't found such class, the namespace does not contain documentation.
// Leave and don't go further.
if (doc is null) return;
// Else, assign the class' Summary and remarks to the Namespace and remove the class from the tree.
node.Summary = doc.Summary;
node.Remarks = doc.Remarks;
node.Items.Remove(doc);
// job finished for this namespace, we do not want to go further down the tree.
return;
}
// For non-namespace intermediate nodes (IE assembly nodes), visit the children.
foreach (var child in node.Items) ExtractNamespaceDocumentation(child);
}
Lastly, I compiled the solution and, by using the newly created docfx.exe located at docfx-2.59.2\src\docfx\bin\Debug\net472, i was able to detect all classes named _NamespaceDoc and use their <summary> tags to fill the namespaces they resided.
For the record, i decided to create a new .cs file at the root of my project to contain all _NamespaceDoc classes, so it would be easier for me to disable the whole file when i want to release the project. This file looked like this:
namespace RootNamespace
{
/// <summary>
/// Documentation for the Root Namespace
/// </summary>
public static class _NamespaceDoc { }
}
namespace RootNamespace.SubFolder
{
/// <summary>
/// Documentation for the Root Namespace's `SubFolder` Sub-Namespace.
/// </summary>
public static class _NamespaceDoc { }
}
// [...]
Hopefully, this may help other fellows seaking for such solution, or even the docfx devs and contributors to implement this feature more reliably.
Update:
For more info about this approach, I've started a discussion
on docfx's github repository
I've got an object declared and instantiated in my Flex application's singular MXML file:
public var CDN:CDNClass = new CDNClass;
I would like to access this same CDN object (and its public methods and properties) in another class declared in a separate .as file as such:
package my.vp
{
import my.media.CDNClass;
public class SyncConnectorManager
{
private function syncMessageReceived(p_evt:SyncSwfEvent):void
{
switch (p_evt.data.msgNm)
{
case "startStream" :
// Play a stream
CDN.parsePlayList(p_evt.data.msgVal);
break;
But when I try to access the public method parsePlayList in the CDN object in a method in the class defined in the .as file, I get the following error:
Access of undefined property CDN
The reason I want to do this is to break up the logic of my application into multiple AS files and have minimal MXML files, probably only one.
Thanks - any help is much appreciated. Perhaps my OOD/OOP thinking is not correct here?
IT depends on your class architecture. For your code to work, the CDNClass instance must be defined and implemented inside your SyncConnectorManager.
Generally, you can always call down into components, but should never call up
One option is to pass the instance ofCDNClass to a variable inside SyncConnectorManager. Add this variable to your SyncConnectionManager class:
public var CDN:CDNClass = new CDNClass;
And at some point do this:
syncConnectorManagerInstance.CDN = CDN;
That way both classes will have access to the same CDN instance and can call methods on it.
Yes, your OOP thinking is not correct here. You should take in mind differences between classes and instances. This line declares a filed in a current class and initiates it with an instance:
public var CDN:CDNClass = new CDNClass;
So current instance of your MXML class (you can think about it as usual AS class with some other notation) has public field. To operate with CDN instance you need something from the following:
Read the value of CDN (as far as it is public) from the instance of your MXML class. You need some reference to it for that.
The instance of your MXML class can have a reference to the instance of SyncConnectorManager and SyncConnectorManager should have a way to inject the value of CDN there. Something like:
Your class:
package my.vp
{
import my.media.CDNClass;
public class SyncConnectorManager
{
private var CDN:CDNClass;
public function SyncConnectorManager(CDN:CDNClass)
{
this.CDN = CDN;
}
private function syncMessageReceived(p_evt:SyncSwfEvent):void
{
switch (p_evt.data.msgNm)
{
case "startStream" :
// Play a stream
CDN.parsePlayList(p_evt.data.msgVal);
break;
In your case SyncConnectorManager class hasn't CDN declared (the problem of the compiler error you mentioned) and instantiated (the problem of NPE even if you just declare field).
As the bottom line I can suggest you to follow ActionScript naming and coding conventions to talk other people and team members about your code :)
i want make own flex library and in this library use own actionscript file which will i use in more component in this library..this file contents eg only code
public function computeSum(a:Number, b:Number):Number {
return a + b;
}
but when i can this create just when i click File-New-Actionscript File (filename - OK) is in Problem view Error: A file found in a source-path must have an externally visible definition. If a definition in the file is meant to be externally visible, please put the definition in a package
thanks for help
You should encapsulate it on class, in order to use it with import directive, else u could use it with include
Another approach is to create a "helper" class, or so called "singleton" class.
- a class having only 1 instance, created statically.
on this class u can expose the library functions which u do need and use them everywhere.
package
{
public class Singleton
{
private static var singleton : Singleton
public static function getInstance() : Singleton
{
if ( singleton == null )
singleton = new Singleton();
return singleton;
}
public function Singleton()
{
}
public function visibleTroughtTheSingletonfunction( arg1 : int ... ) : void
{
}
public static function directlyVisiable() : void
{
}
}
}
the accessing the singleton would be something like :
Singleton.getInstance.visibleTroughtTheSingletonfunction( 1 );
OR
Singleton.directlyVisiable();
depending on your needs.
Well first you'll need to create a class (and a package) and put that method inside that (not just into an empty AS file) and second if you want to be able to access the method without creating an instance of the class make this method static.
If you don't need to change the class file during runtime then make action class compile into swc library.
create a Action script project and compile it in the bin folder you found the .swc library file. include that .swc into your project .
I am just learning actionscript, so come across the problem
In my application I often call to different web services, and because I don't want to hardcode urls to them in my code, I am passing urls to the services as flashvars.
Currently I am doing it this way:
public var siteUrl:String;
public var gameId:String;
public function main():void
{
siteUrl = Application.application.parameters.siteurl;
gameId = Application.application.parameters.gameid;
Where main is a function, which is called on application's creation complete event.
This way I can call both variables from main file of the application but I want to access them from other files. (other as classes)
So is there a way to create class with constants and init values there with flashvars so I can use them everywhere (after importing of course)
The parameters are just stored in that Application.application.parameters object, and that's static. There's no reason you couldn't access that from other classes in your code.
If you want to write a class that wraps the parameters (maybe validates them or something) you could do that fairly easily. You can use a for each loop to loop over all the parameters. Something like:
var params:Object = Application.application.parameters
for(var name:String in params) {
var value:String = params[name] as String;
/* do something with the param */
}
If you want your class to actually verify things then it could just check for each parameter it expects and store it in a local variable.
It really just depends on your own preferences. Some people are fine with accessing the parameters object when they need it. Some people like having the extra code-completion by having a config class that actually defines all the expected config variables.
Update in response to comment:
Instead of having one module declare the variable and have other modules have to depend on that one to access the property it would be cleaner to have a single config module that everything that needs it would all use.
You could use a static class or singleton or some IoC stuff. Just for simplicity I'll show you a way you can do it with a static class.
class MyConfig {
private static var _infoService:String;
private static var _someOtherParam:int;
public static function get infoService():String { return _infoService; }
public static function get someOtherParam():int { return _someOtherParam; }
public static function initParams():Void {
var params:Object = Application.application.parameters;
_infoService = params.infoservice;
// just assuming you have a method to convert here. don't remember the
// code off the top of my head
_someOtherParam = convertToInt(params.someOtherParam);
}
}
Make sure when your app initializes it calls MyConfig.initParams(). You can have that method actually validate that it gets everything it expects and throw exceptions (or return an error) if there's a failure if you want.
Then wherever you need to use that config within your code you just import your config class and access the param. So getting infoService would just be:
var infoService:String = MyConfig.infoService;
Personally I wouldn't use a static class, but it was the easiest to show.
I have this small app that loads plugin type components that other users can freely upload to the server. But I don't want the users to be able to access other users files. I need to set the access of each plugin component to a restricted access.
I tried to set the access inside the plugin classes base class but even then the loaded plugin classes seem to have full file access.
I can't set the permission with a attribute because the path changes depending on who loads the page.
Here is a code snippest:
public abstract class PluginBase<T>
{
public PluginBase
{
PermissionSet ps = new PermissionSet(System.Security.Permissions.PermissionState.None);
ps.AddPermission(new System.Security.Permissions.FileIOPermission(System.Security.Permissions.FileIOPermissionAccess.PathDiscovery | System.Security.Permissions.FileIOPermissionAccess.Read, HttpContext.Current.Server.MapPath("/app_data/www_somesite_com")));
ps.PermitOnly();
}
}
public class SomePlugin : PluginBase<SomePlugin>
{
public SomePlugin
{
File.WriteAllText("c:\test.txt", "This should not be possible, but it is.. why?");
}
}
Many thanks in advance!
The solution is actually quite simple, as you can implement your own attribute (which allows you to resolve the allowed path programmatically instead of having to use a constant for the decorator attribute).
using System.Security;
using System.Security.Permissions;
public sealed class CustomFileIOPermission : CodeAccessSecurityAttribute
{
public CustomFileIOPermission(SecurityAction action)
: base(action)
{
}
public override IPermission CreatePermission()
{
// You can use your `HttpContext` or similar at this point to resolve the path
string allowedPath = #"D:\test";
return new FileIOPermission(FileIOPermissionAccess.Write, allowedPath);
}
}
The class above will enable use of [CustomFileIOPermission(SecurityAction.PermitOnly)] and will effectively protect files elsewhere.