I have a C++ application which has written for years. There are a lot of classes.
Every time we want to change some parameter values, we need to manually update them in the code and recompile it. It is not convenient as the growing demands of the users. We would like the values of the classes to be configured out side of the application. Probably, reading form an xml is the best? for each user, we can make an xml configuration setting and send it together with the application. Is it a good approach?
For every class e.g: Class classA, should we create another class called: ConfigClassA then classA will use the configuration setting from ConfigClassA? We dont want to make a lot of changes in the current implementation.
Suppose there is a structure of an xml file:
<classes>
<class name="ClassA">
<variable id="isUp" value="true" />
</class>
</classes>
In Xml, we can get the portion classA and parse it to ConfigClassA then classA has an instance of ConfigClass.
Or anybody has a better approach?
Thanks in advance.
In general I think that the whole configuration should be loaded when an application is launched, so you can immediately notify the user in case of an invalid configuration. In order to validate an XML file, you can use XML Schema.
However, if you don't want to make a lot of changes in the current implementation, your idea could be a valid solution.
Using JSON or YAML will be more lightweight than XML, since the parser of the config file will be simpler. Anyway, XML is also feasible.
It's actually quite common to have configuration files. The format in which they are stored is not important. They are usually loaded only once, at the beginning of the program, not queried each time a method requests something.
Also, you should make a tool available for editing these files (such as a "Preferences..." panel).
Related
I have a controller which duty is copying a file passed along with the request (through a body POST) to a specific path under web/images. The path is specified by a property living into the specific Controller.
What I would like to do is testing it with a functional test, but I wouldn't like it to overwrite files in my project, so I would like to use vfs or change the path before my test case sends the request.
Is there a good-straight way to accomplish this?
A common approach is to load configuration that may change between environments as an environmental variable. (I have not ever used symfony before, so there may be tools to help with env vars)
The upload path could then be
$upload_path = getenv('WEB_IMAGE_UPLOAD_PATH') ?
getenv('WEB_IMAGE_UPLOAD_PATH') : 'web/images'
This will allow you to specify a temp (/tmp ?) directory when starting up your server in integration mode.
Ah cool, (disclaimer: i'm not a php person) it looks like php has IO streams that may be able to help in functional testing, and allow easy cleanup.
http://php.net/manual/en/wrappers.php.php#refsect2-wrappers.php-unknown-unknown-unknown-unknown-unknown-descriptios
I believe you may be able to set your 'WEB_IMAGE_UPLOAD_PATH' to be one of those streams
I'll try to answer myself: I refactored my code in order to have a property that specifies the path I would like to copy/overwrite my file.
Then, inside a PHPUnit class I replace the object property's value with a vfsStream path. By doing like that I get the behavior I need, without touching my real files/paths. Everything will live inside the virtual file system and my object will use it.
Parameters are important for a clean and reusable code, but even more when you want to unit-test: I think Unit testing is helping me to force to parameterize everything in place of relapsing to hardcoding when you don't have so much time. In order to help me writing unit tests I created a class that accesses methods and properties, irrespective of their accessibility.
PHPUnitUtils
I'm quite sure there's already something more sophisticated, but this class fullfills my needs in this very moment. Hope it helps :-)
I created a unit test in which I dynamically create and then parse an xml. When I'm finished with the file I delete it. I'm storing the file momentarily in a created resource folder within my project,but I want to know will this still pass if I deploy to a tomcat server. I'm using getRealPath () right now and it works. I in no way need these files later on which is why I'm deleting them.
I've read the getRealPath () isn't portable and shouldn't really be used but that's why I'm asking for my purpose would it be ok?
I can't post code because I'm at work but I'll try to explain somewhat:
I use ServletContextHolder.servletcontext.getRealPath () and add resources/testfiles to the end..this takes me to my project path (project/out/test/resources/testfiles)
I create an xml file using stringwriter,filewriter,markupbuilder..
I save this file, read it and delete it after the test..it works on windows but I need to know if it'll work on tomcat if it is deployed and the unit tests run automatically..will it be able to do all this..
Apologies for poor format my phone isn't the best way to write this
The ideal solution would be to not use files at all. But it really depends on what class your XML parser uses for its input. For example, if the parser accepts an InputStream, you can use a StringBufferInputStream to build your XML content. The parser would then be able to use that stream as if it were a file. OOP interfaces are awesome like that :)
I'm working on a widget, for reordering menus.
For this purpose I have added few buttons like MoveUp, MoveDown, Add, Delete which are supposed to change the order of menus in the XML file, as XML file is being read for populating menus.
Now my question is that I have applied file open, write and close operation for every click of these buttons, which instantly changes into xml file. It is relatively easy way for me. Given that, the widget has comboBox too, which read from xml and then populate current order of inner level submenus in the widget. ( same like : MS outlook->tools->customize->RearrangeCommands)
My XML file is a small one around 1.5K.
I want to know which option would be better?
i) The one I mentioned above, opening-reading-writing XML files for every mouse click.
ii) Creating a data structure which once reads the file, stores the data and all activity happens with this data and then finally OK buttons write the data into actual XML file.
I personally like option (i) which is very easy to implement overall.
And if (ii) one is better option then what data structure should I use?
XML file format is like :
<menu>
<action id="1">menu1</action>
<action id="9">menu2</action>
<submenus id="5" name="submenus 1">
<action id="17">menu14</action>
</submenus>
<action id = "10">menu1</action>
<submenus id="7" name="submenus 1">
<action id="3">menu14</action>
</submenus>
<action id="11">menu2</action>
</menu>
Trade-off between frequently reading/writing a small file and once reading, creating a data structure to store data and finally writing only once, which one is better option?
Note : I'm using QT DOM with c++ for all this purpose.
I know this is not c# but I am not too fond with c++, so if someone could fill in my blanks, that would be awesome
In C# you can just load your Xml into an XDocument object and do the manipulations in memory, aka instant.
When done you save them to file.
This has the disadvantage that when you crash, your changes are gone.
To migitate this you can save in a spefified intervall.
Advantage is that you can get rid of your frequent file accesses.
The question IF there is a performance penalty depends on the way you do the IO operations:
If you do them async you don't loose much time even if your OS is a bit occupied, sync strongly depends on your OS' performance, in particular the business of the file system.
Also too frequent file operations wear off the storage device. I know we're probably not talking about EEPROM here with ~10k IO-cycles, but still.
Can someone let me know wether there is a namespaces/library for c++ that provides similar functionality?
I think writing configuration directly into a file is bad practice. Imagine that you want to get the order of menus in some other code. For example, if "File" menu is hidden or moved, you want to display a message box in some moments.
Now you need to open the XML and parse it each time you want to get this information. You need to duplicate code needed for parsing XML and getting menus order from it.
If you had a structure containing your settings, you could just store it somewhere in a variable and use it any time you want. No duplication, more clean code, easier to write unit tests.
Generally, I know from my experience that creating a structure for settings is good. This approach looks harder at the start, but most likely will save you time in the future.
In our project we got an application that uses an external configuration file (say server.xml). Now we need to design a setup tool GUI in C++/QT to read/edit such configuration file and it should be able to handle all the different versions of such file. The user will choose the file version and then proceed with the editing. From one version to another doesn't change too much, maybe there is a new xml tag, a tag with a different name or in a different position.
What's the best design approach to do so? We are planning to go for a standard MVC design pattern but how to deal with all the different configuration versions without rewriting the same GUI code again n again?
Here the sample config file:
<?xml version="1.0" encoding="utf-8"?>
<Server_configuration ver="11">
<core>
<enable-tms>true</enable-tms>
<enable-gui-messages>true</enable-gui-messages>
<waiting-for-config-timeout>10000</waiting-for-config-timeout>
<remoting>
<port>50000</port>
<join-timeout>5000</join-timeout>
<ismultithread>true</ismultithread>
<maxconcurrentrequests>20</maxconcurrentrequests>
</remoting>
</core>
<content>
<ftp>
<ip>192.168.0.227</ip>
<port>21</port>
<userid>******</userid>
<passwd>******</passwd>
</ftp>
<library>
<ip>192.168.0.227</ip>
<port>50023</port>
</library>
<local>
<asset-root>/assetroot</asset-root>
<kdm-expiration-warning>172800000</kdm-expiration-warning>
</local>
<hula-store-daemon>
<ip>127.0.0.1</ip>
<port>5567</port>
</hula-store-daemon>
</content>
</Server_configuration>
This is no means a drop in solution but I here are some things to do/consider. Every situation will differ.
Have an explicit version identifier in your config files. Fingerprinting them is a real (error prone) pain.
Consider having a tool that will update from version to version. It will be easier than reading old versions and trying to apply them.
I may be easier to do every version step individually but this can make the conversions less "lossless". A happy hybrid is to do minor updates from version to version but have "checkpoint" major upgrades that will jump right to the latest (or the latest "checkpoint"). This is kinda like incremental backups with full backup snapshots every once and a while.
Keep the user informed. A sysadmin won't be happy if you are changing his settings. You might want to make the process interactive or put comments into the file of every added/moved/removed setting. I would also recommend keeping removed settings in some section of the file for user reference. (Put a note why they are there as well).
Backup the old file. Your script will crash and it will eat data. Do something like naming the current file ${oldname}.old-${ver}~. Saving the settings in a different section of the file won't always be enough and this will save your users a lot of heartache.
Versioning should always be designed as robust and as simple as possible. It is crucial for you to determine whether each version of your application must be compatible with each version of the setup tool (which is rare), or whether you can, for example, meet your needs if any newer setup tool works with any same or older application, but not vice versa.
One way compatibility
One possibility to design for the latter is to add a version attribute to the XML file but try to keep it at the same fixed value forever by always only changing the structure and semantics of the XML file in backward compatible ways. For example, adding an element is backward compatible as long as the setup tool can interpret its absence the same way both the old setup tool and the application would behave. It does not hurt that the new setup tool always writes an (equivalent) value to the new element, because two-way compatibility with the old application is not required.
Once the day comes when you cannot maintain backward compatibility on input, you just change the value of the version attribute and start special casing it in the setup tool.
If you validate the XML against an XSD, notice that XSD can actually do one frequently useful thing for you: assign default attribute values. This way, your setup tool's source code may not even actually notice that the underlying document was missing a recently added attribute!
Two way compatibility
Strict versioning is needed. A schema definition (XSD, RelayNG,...) should be defined for each version of the XML file and the file should be validated against it both when it is read by the setup tool, written by the setup tool, or read by the application. The schema definition may be identical for several consecutive versions, if the interpretation of the same XML has changed, so when in doubt, always increase the version number.
Do what you can educating everyone that they cannot just edit the latest schema and do away with that. Unreliable versioning is worse than no versioning.
OK, so here's the background:
We have a third-party piece of software that does a lot of complicated stuff to generate an XML file from a lot of tables based on a wide array of business rules. The software allows you to apply an XSL transformation by supplying an XSLT file as part of its workflow, before continuing on in the process, which is usually an upload to one or more servers, based on more business rules.
Here's the problem:
One of the elements (with more on the way) this application is processing contains RTF text, and needs to be converted into formatted HTML before being uploaded. There are no means of transforming the XML inside the application other than through an XSLT file, and once we output the file, we cannot resume the workflow. My original thought was, "Easy! someone must have written a few XSL transforms for converting RTF to formatted HTML!" Hours of searching later, I must conclude I either suck at searching or it's awfully obscure.
Disclaimers:
I know the software is pretty darned limited; I'm stuck with it.
I know there are a lot of third-party tools to do this; they are not available to me because I would need to run them externally.
I know that this is not a pretty or efficient thing to do with XSLT. Changing that is not an option for me at this point.
If I cannot find a means to do this through pure XSL transforms, I will need to output the files locally, run the extra process, and take the destination routing on through a custom process. I really don't want to do that.
Does anyone have access to an XSL transformation function/ scheme that will allow me to do this natively in the application? Perhaps a series of regular expressions I could use or something?
So it turns out that external scripts can be invoked from the XSLT. It seems I will be using another scripting language to get this to work. I'm a little bummed there was no other answer available.