Extension modules VS web-extension when customizing Alfresco Share - customization

Well I'm working since some months ago with Alfresco 4.2b, mainly with Share. I'm preforming some customization works and my colleagues and myself are always wondering about the subject of this post.
We know extension modules is a relatively new feature which is available since the first release of Alfresco 4 but we don't know which way should the developments performed take in terms of the extension mechanism used. We are putting all our efforts on using the extension module mechanism rather than using the web-extension directory. We are doing that because we understand that probably the it is more versatile, maintainable and scalable and who knows, perhaps the use of the web-extension directory could be deprecated in further releases. We are also aware that at the moment you cannot do "everything" with extension modules.
So according to that, I would like to know about pros and cons of both mechanisms based on other developers experience, as well as whether we are doing right with our extension philosophy. At the same time, I would like to find a reasonable answer to the next questions:
Are we doing right prioritizing and "sacrifice" our time trying to perform customization with extension modules? Is it worth?
Could be deprecated the web-extension directory as a customization mechanism in further releases?
Is the extension modules feature going to be improved?
(Roughly) known limitations of extension modules? Mainly the question could be, when should be used one extension mechanism or the other?
I'm looking forward to hear your opinions. It would be strongly appreciated opinions based on your real experience and as honest as possible.
Thanks very much in advance.

Actually both are not exclusive.
I'm using myself for instance the extension mechanism to define new components which webscripts are defined in the web-extension folder.
In fact the extension module itself can be located in the web-extension folder under alfresco/web-extension/site-data/extensions/...
For me using the extension modules is a way to logically package (because of the deployment process of modules) your customization. That's the main advantage because it can be configured through evaluators if you want the customization to be available only in particular conditions.

The two main problems with the web-extension route is that you will end up duplicating core code in your customisation, and that if multiple extensions try to extend the same component, one must win.
Extensibility modules may be a little bit more work but you will more than get that back in terms of a much reduced maintenance burden, and in troubleshooting problems when multiple add-ons clash with each other.
From 4.2 onwards you should not need to override web script components - in Share at least. You should always use an extensibility module.

Related

Using boost-di with configuration file and shared libraries

I am planning a c++ project using dependency injection via boost di. In my opinion I will need a mechanism for dynamically loading libraries too, to be able to realy benefit of dependency injection.
Therefore I consider using boost dll to use a platform independent shared library mechansim.
For dependency configuration I think about using INI-files via boost property tree.
Do you see any major drawback in this approach?
Or is there another platform independent mechanism/library?
Thanks for your opinions
Andreas
There is a mechanism to decide during runtime what implementation to use. But due to the compile time approach of Boost DI it seems by design not intended to use it with dynamic libraries.
For a pure compile time injection it looks very smart and nice to use. For my problem, it seems not the right solution.
During C++ projects development, I had to find a C++ DI framework.
After some investigation and evaluations and based on our requirements (detailed below), we found out that Hypodermic framework suits our needs.
Our criterions (except the basic one that the framework shall recursively inject instances !!) were:
Non-intrusive (do not require to dirty existing code with 'decorations' macros...) as Google fruit and or other libs require.
Support singleton instance
Support of configurable instantiation (using a lambda)
Support of container\injector composition
Generic Shareable container\injector in order to support modules (static or dynamic). BTW, I agree with
Boost-DI, as answered by Andreas, is not suitable because it is heavily templated and as answered in this question.
Boost-DI does not allow real composition of containers at run-time and even not at compile-time unless you share the header files with the root injector. It violates the 'privacy' of modules (as you need to publish them to be able to inject them).
Hypodermic allows to configure containers and create sub-containers. Container is agnostic to type (not template) therefore it is possible to share it at run-time.
BTW, this solves also this question

is there an API for GIT (C++ or other languages)

A company asked me to program a GIT wrapper for them.
The people there have absolute no versioning systems experience, but it will be incorporated in their daily routine eventually (through my program).
I'm planning on using VC++ to create a tiny windows applet that will help ppl in this process. Any thoughts on that?
What about a Deamon process checking if people want to commit/push their files?
For almost (but not all!) use cases, libgit2 is the easiest way to interact with Git repositories via code.
Git already has two layers: The plumbing (which you may be interested in) on top of which is built the primary porcelain which provides the user interface. If you want to implement something like git-commit but with slightly different semantics all of the underlying programs like git-write-tree and git-rev-parse are there for you to build on.
See also What does the term "porcelain" mean in Git?
There's already TortoiseGit, among other "friendly" interfaces. Don't re-invent the wheel, start by researching what's already available.
In order to easier the search for documentation hereafter the link to the official. It's about the plumbing and porcelain:
https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain

CppCMS vs. C++ Server Pages vs. Wt

I know Wt is the most stable of them, but it's a bit uncomfortable to use.
CppCMS sounds good but how stable is it? How secure is it?
I have encountered C++ Server Pages as well but there's nothing about their security in there.
Has anyone had some experience with any of those libraries and can enlight me?
First of all, several differences:
Wt is GUI like framework, it is quite far from traditional web development. So, if you
want to develop a code as if it was GUI it is for you.
CppCMS is traditional MVC framework optimized for performance, it has many features like template engines, forms processing, i18n support, sessions, efficient caching and so on, support of various web server APIs: FastCGI, SCGI and CGI. If you come for Django world, you would find yourself at home.
I'm less familiar with the third project, but it feels more like PHP -- you put the
C++ code inside templates and has no clear separation of View and Controller.
Stability, I can tell only about CppCMS, it is stable, and there are applications running
it 7/24, the authors blog and the Wiki with documentation of CppCMS are written in CppCMS.
So, there shouldn't be major critical bugs.
Disclosure: I'm developer of CppCMS.
I am the developper of libapache2-mod-raii and I am very disappointed we did not recommend this library for production work... Cause I do ! :)
I also like to point out that the project page is also available in English.
On the other hand, I do not agree with Steve about the fact that servlets are not compiled on the fly, as they are !
Otherwise, on the lacks of prefork support is not my point of view, although I was looking on the issue.
On a side note, I used mod_raii a while ago to rapidly port some parts of an existing C++ application on the web.
It takes exactly the same approach than JSP, with the whole compilation part delegated to the Apache module.
I cannot recommend it for production use, since I don't have much experience in it, but it is definitely something worth playing around with, and I didn't have any issue at the time.
It lacks some features like the support of a preforked apache, but has all the needed core features.
Answer from 2018:
I am running on limited hardware resources, so C++ is the first thing I think of. I made a decision by looking at this benchmark of web frameworks. cutelyst (a Qt derivative) and Wt dominate the top spots. They are all non-libre. So, I looked into treefrog. Right after its first and only tutorial, it is apparent that it uses qmake from Qt and thus Qt's LGPL applies.
I reluctantly go with CppCMS at the bottom of the list, as ffead has too many errors and poco is not a fullstack framework.
Diving into the tutorials, CppCMS is way ahead of treefrog when it comes to documentations. The first several tutorials are easy to follow. However when I start encountering problems, help is almost non-existent. I can't imagine how it would be like going with treefrog to get something done. Lack of documentations (and good ones) is the reason why I dumped it in the first place.
I almost dumped CppCMS also due to a serious roadblock. A tiny community cannot offer much help. Got Laravel (a very popular PHP framework) installed and about to test something. Then, the CppCMS issue seemed resolvable and I am back to it. Guess I am about to get stuffs done with CppCMS but its constraints are showing.
The incident got me thinking, and I look back at the benchmark, allowing Java and PHP to be there. I need some alternatives in case things don't work out. Lo and behold, the top three spots are occupied by Java frameworks. Laravel may not be the fastest, but it is really hot right now. Plus, I can call my C++ executables from PHP codes.
According to this discussion: if you use Qt with dynamic linking, it seems that you do not have to disclose your code if you use Qt with dynamic linking. This has to be researched, and Qt cannot be mastered within a single day. I suppose that makes cutelyst a possible choice again, IF AND ONLY IF you can do dynamic linking, and do all your things that way. I am just not a fan Qt's legal minefield and jumping hoops.
Through all this, I have a different look towards Java. Will still do Laravel because of all the rage, and I am now open to things other than C++.

What Linux Full Text Indexing Tool Has A Good C++ API?

I'm looking to add full text indexing to a Linux desktop application written in C++. I am thinking that the easiest way to do this would be to call an existing library or utility. This article reviews various open source utilities available for the Gnome and KDE desktops; metatracker, recoll and stigi are all written in C++ so they each seem reasonable. But I cannot find any notable documentation on how to use them as libraries or through an API. I could, instead, use something like Clucene or Xapian, which are generic full text indexing libraries. They seem more straightforward but if I used them, I'd have to implement my own indexing daemon, an unappealing prospect.
Also, Xesam seems to be the latest thing, does anyone have any evidence that it works?
So, does anyone have experience using any of the applications or libraries? How did you use it and what documentation was useful?
I used CLucene, which you mentioned (and also Lucene.NET), and found it to be pretty good.
There's also Strigi which AFAIK works with Xesam and is the default used in KDE.
After further looking around, I found and worked with Recol. It believe that it has the best C++ interface to a full text search engine, in this case Xapian.
It is important to realize that clucene and Xapian are both highly complex libraries designed primarily for multi-user server applications. Cutting them down to a level appropriate for a client-system is not easy. If I remember correctly, Strigi has a complex, pure C interface which isn't adapted.
Clucene also doesn't seem to be that actively maintained currently and Xapian seems to be maintained. But the thing is the existence of recol, which allows you to index particular files without the massive, massive setup that raw Xapian or clucene requires - creating your own "stemming" set is not normally desirable, etc.

Common libraries in a large team

Assume you have five products, and all of them use one or more of the company's internal libraries, written by individual developers.
It sounds simple but in practice, I found it to be very difficult to maintain.
How do you deal with the following scenarios:
A developer unintentionally introduces a bug and breaks everything in production.
Every library has to mature, That means the API needs to evolve, so how do you deploy the updated version to production if every developer needs to update/test their code while they are extremely busy on other projects? Is this a resource and time issue?
Version control, deployment,and usage. Would you store this in one global location or force each project to use, say, svn:externals to "tie" a library?
I've found that it is extremely hard to come up with a good strategy. My own pet theory is this:
Each common library has to have a super-thorough set of tests or else it should never be common, even if it means someone else duplicates the effort. Duplicate untested code is better than common untested code (you break only one project).
Each common library has to have a dedicated maintainer (can be offset by a really good test suite in a smaller team).
Each project should check out the version of the library that is known to work with it. This means a developer does not have to get pulled away to update API usage, as the common code gets updated. Which it will be. Every non-trivial piece of code evolves over months and years.
Thank you for your thoughts on this!
You have a competing set of goals here. First, a library of reusable components must be open enough that people from the other projects can easily add to it (or submit components to it). If it's too difficult for them to do that, they'll build their own libraries, and ignore the common one, leading to a lot of duplicate code and wasted effort. On the other hand, you want to control the development of the library enough that you can ensure its quality.
I've been in this position. There's no easy answer. However, there are some heuristics that can help.
Treat the library as an internal project. Release it on regular intervals. Ensure that it has a well-defined release procedure, complete with unit tests and quality assurance. And, most important, release often, so that new submissions to the library show up in the product frequently.
Provide incentives for people to contribute to the library, rather than just making their own internal libraries.
Make it easy for people to contribute to the library, and make the criteria clear-cut and well-defined (e.g., new classes must come with unit tests and documentation).
Put one or two developers in charge of the library, and (IMPORTANT!) allocate time for them to work on it. A library that is treated as an afterthought will quickly become an afterthought.
In short, model the development and maintenance of your internal library after a successful open source library project.
I don't agree with this:
Duplicate untested code is better than
common untested code (you break only
one project).
If you are all equally likely to create bugs by implementing the same thing, then you'll all have to fix potentially different bugs in each instance of the "duplicate" library.
It also seems that it'd be much faster/cheaper to write the library once and, instead of having multiple other teams write the same thing, have some resources allocated to testing.
Now to solve your actual problem: I'd mimic what we do with real third-party libraries. We use a particular version until we're ready, or compelled to upgrade. I don't upgrade everything just because I can--there has to be a reason.
Once I see that reason (bug fix, new feature, etc.), then I upgrade with the risk that the new library may have new bugs or breaking changes.
So, you're library project would continue development as necessary, without impacting individual teams until they were ready to "upgrade".
You could publish releases or peg/branches/tag svn to help with all this.
If all teams have access to the bug tracker, they could easily see what known issues exist in the upgrade-candidate before they upgrade, too. Or, you could maintain that list yourself.
#Brian Clapper provides some excellent guidelines for how to run your library as a project in his answer.
I used to work in a similar situation to what you're describing, only my company had dozens of software products. I worked on the team that was responsible for maintaining and upgrading the core set of libraries that everyone else used.
We dealt with those scenarios as follows:
Test the heck out of the core libraries. Maintaining duplicate code is a nightmare. You're not just maintaining the core and one copy. Somewhere in your company's source control there are several copies of the same code. We had dozens of products, so that would have meant dozens of copies. Hunt them down and kill them.
We had a small team of 10-12 developers dedicated to maintaining the core library and its test suites. We were also responsible for fielding calls from the other 1100 developers in the company about how to use the core library, so as you can imagine, we were very busy.
Each other project needs to work with the version of the core library that it is known to work with. You can use version control branches to test new releases of the core library with old products to make sure you don't break code that works. If the core team does a thorough job of testing, this should go very smoothly. The only time this ever got really complicated for us was when the core API changed, or when we flat out screwed something up. Even if you're very confident in your core testing, use branches to test individual products.
I agree - this is difficult. In our small team (consulting .. not a product company - which made it harder), we had one common component that stood out from the others. In this case the recipe for success was:
Make a good developer responsible for developing the component
Make a good developer the gatekeeper for maintaining the component
Make sure all upgrades (there were several) are backward compatible
Make sure there is some basic documentation (or a simple reference application) explaining how the component is to be used
Make sure all developers know that the component exists (!) and where they can find it (along with the code, if they wish to review it)
Give developers the ability to review the code and suggest better implementations or refectoring, but have the final mods go through an experienced gatekeeper. When the component were upgraded, older apps did not have to upgrade. If we did a new release, we evaluated if we wanted to upgrade, and if we did, all we needed to do was swap the libraries - no code needed to change, unless we wanted to use some new features available through the upgrade. Resistance is inevitable, but sometimes it is a good sort of resistance when it comes from good developers who have better ideas for a new generation or refactored component.
Treat the development of the libraries like any other product. Each library has its own repository, its own releases and version numbers. The compiled and officially tested versions of the library are also kept in the repository. Document features and changes from version to version.
Then use the libraries like you would using third party libraries. Your product uses only fixed versions of the compiled libraries. Switch to a new version when you really need to and be aware that this involves more testing. Add the versions you use to your version control.
When you find a bug or require a new feature in a library, a new version or sub-version is created. Using a version control system like svn makes this easy. When you need the source code for debugging purposes, export it and include it in your projects, but do not change it there, but fix problems in the libraries' repositories.
This way, every team can contribute to the libraries without endangering the work of the other teams. Switching versions is done deliberately and not by accident.
Create an Anti-corruption (DDD) layer for the existing library... this is nothing but a facade.. and then write unit-test for this anti-corruption layer... Now even if someone upgrade/update the library you would know if something is broken by running the unit tests...
These tests could also serve as documentation of contract... and not every project that need to use the library has to write this anti -corruption layer, if they are using the same exact functionality..
"Duplication is the root of all evil"
Sounds to me like you need:
An artifact repository like Ivy so you can have the libraries shared and versioned with a distinction between versions that are API stable and ones that are "maturing"
Tests for the libraries
Tests for the projects using them
A continuous integration system so that when an incompatibility or bug is introduced both the project and the original library developer are notified
I think that one shared library is better than 3 duplicate ones (and 1 tested is definitely better than 3 untested). That's because when you find and fix problem, this makes the whole application area more solid (and development and maintenance are more efficient).
BTW, that't one of the reasons (apart from contributing back to the community) why our company exposes our .NET shared libraries to the public as open-source.
Plus, there's less code to write. And you can designate one dev to enforce good development practices on the library and its usages (i.e. through code contracts enforced on the unit tests within library consumers). This improves quality and and reduces maintenance costs.
We store shared libraries as binaries in the solution. That comes from the logical requirement that any solution has to be atomic and independent (this rules out svn:externals links).
API compatibility is not an issue at all. Just let your integration server rebuild and retest the whole product stack (while updating all the inner references and propagating changes) and you'll always be sure that all internal API's are solid. And whomever breaks the API has to either fix it or update the usages.
Duplication is the root of all evil
I would argue that unchecked government is the root of all evil :)
I do get a lot of flack for even suggesting that duplication should be an option. I understand why, but let me complicate this a bit.
Say you have a fairly large library that doesn't actually do anything in particular - it's just a collection of utilities. There are NO tests for this library - at all. You need only one function from it. Say, something that parses out a file's extension.
Pop quiz: do you just write something as small as this in your own project, or you bite the bullet and use the free-for-all untested set of utilities, which WILL break your application if someone breaks the function?
Also, imagine you are in environment where writing tests is not part of the culture, since most projects are very intense and have a very short development span.
Duplicating large systems - such as client registration - would be dumb beyond belief, of course. However, aren't there any cases where it is safer to duplicate something fairly small in your project if the alternative is not safe enough (no system for maintaining common code).
Think of it this way - and this happens all the time - multiple contractors working on different projects, for the same company. They don't even know about each other.
My argument is this:
If a team cannot dedicate to maintaining a solid common codebase, or if the environment does not give them enough time to, it's best to let them work as separate "contractors".
You will STILL need to use large existing systems that simply cannot be duplicated.
Duplicating large systems - such as
client registration - would be dumb
beyond belief,
That's why those systems publish external interfaces.
If you define a library as shared code between projects: in my experience that's almost always bad. A project should be stand alone, and updates for one project should not affect other projects.
Even if you start with libraries, you'll end up duplicating code anyway. Want to hotfix project 1? It was released with library 1.34, so to keep the hotfix as small as possible, you'll go back to library 1.34 and fix that. But hey-- now you did exactly waht the library was supposed to avoid-- you've duplicated the code.
Every developer uses Google to find code and copy it into his application. That's probably how they found Stack Overflow in the first place. Imagine what would happen if Stackoverflow published libraries instead of code snippets, and you'll get an idea of the problems that afflicts many well meaning library creators.
Libraries tend to be generic solutions to specific problems. Typically, the generic solution is more complex than the sum of the two specific solutions. This means you need one good programmer to solve a problem that could have been solved by two morons. Sounds like a bad tradeoff to me :D
I would like to point a problem in the solutions suggested above: treating the library as an internal project with its own versioning scheme.
The problem
If your company has more than one product (lets say two teams - two product: A, B), than each product has its own release schedule. Let's give an example: Team A is working on product A v1.6. Their release schedule is two weeks from now (suppose Oct 30th). Team B is working on product B v2.4. Their release schedule is 1.5 months from now - Nov 30th. Lets assume both are working on acme-commons-1.2-SNAPSHOT. Both are adding changes to acme-commons, as they need it. Couple of days before Oct 30th, team B introduce a change which is buggy, to acme-commons-1.2-SNAPSHOT. Team A is getting into stress mode since they discover the bug 1 day prior to code freeze.
This scenario shows that treating a common library as a third party library is almost impossible. The trivial, but problematic, solution is for each team to have their own copy of the version they are about to change. For example, product A v1.2 will create a branch (and version) for acme-commons named "1.2-A-1.6". Team B will also create a branch in acme-commons called "1.2-B-2.4". Their development will never collide and they will be stress free once they tested their product.
Of course, someone will have to merge their changes back to the original branch (lets say master or 1.2).
The problems I found with this solution is:
Branch inflation - the tree structure will be very puffy and it will be harder to understand the flow of changes/merges.
Merges back to 1.2 will probably never happen - Unless a team/developer is dedicated to this library, the chances that Team A or Team B merges their code back to 1.2 branch is slim. They will always stay focused on their tasks, thus creating and using their own branch space. Allocation of a developer/team is expensive, thus not always a viable solution.
I'm still trying to figure this one out, so any thoughts of this matter are welcome