To merge or join pdf files with ghostscript, from the command line:
"c:\Program Files\gs\gs9.06\bin\gswin64.exe" -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=join.pdf -dBATCH ch01.pdf ch02.pdf ch03.pdf ch04.pdf ch05.pdf ch06.pdf ch07.pdf ch08.pdf ch09.pdf ch10.pdf ch11.pdf ch12.pdf ch13.pdf AppA.pdf AppB.pdf
Change the command appropriately for your operating system and files.
A pity gsview does not provide a GUI for doing that.
In this post I document a simple domain model that I have used to implement access control in my projects, the first time being sometime around 1998. I have since seen similar approaches to access control elsewhere, so you may already be familiar with it.
The approach mentioned here assumes that authentication is already done, you get some kind of user ID, and have to make the access control decision. It is different from resource oriented access control mechanisms, such as access to files, database structures and so on.
The entities or classes
The primary entities in the domain are:
- User – Represents a user. Each user is identified by a unique ID.
- Action – Represents an action in the system e.g. Log into the system, View users, and so on. I have also called this Operation or Function in the past. Each Action is identified by a unique ID.
- Profile – Represents a set of users e.g. System administrators. Each profile is identified by a unique ID. Profile may also be called Group, if you find that more convenient.
The entities or classes are related in the following manner:
Profile-Action – The actions each profile can perform (or has access to).
User-Profile – The profiles each user is associated with.
Making the access control decision
The decision can be implemented at the point in the code where the action is performed. You need to get a list of all actions the user can perform by traversing from User-Profile to Profile-Action. If the ID of the Action is found to be associated with the User, she is granted access.
Although not the focus of the post, password based authentication can be handled by adding a password hash to the User entity. The authentication decision can be implemented in a front controller and the user ID stored in the session for access control decisions downstream.
I forget the number of times I have written the same code in a different language. Technology changes all the time. If you are a professional developer, it may change from one project or task to another. How can we learn, use, and unlearn stuff so rapidly? I present a few points to ponder in no particular order.
Think in abstractions and patterns
The better your capacity to abstract and think in patterns, the more reusable your knowledge. Apply what you know works. Technology itself is an abstraction, think community and tools.
Read on the topic
Prepare. Go deep. Read a book. Read what the internet has to offer. The more prepared you are, the better you perform. Time is ticking.
Write a blog or book
Share your knowledge with the future you. A better you. Others may find it useful too. Improve over time.
Learn emotional detachment
Don’t reinvent. Don’t be too attached to your work. Appreciate feedback. Change. Move on. Unlearn. Relearn. Collaborate.
Experience is never going to substitute the fact that you need to be creative. Think originally. Have the courage to implement your ideas. If you don’t act, you’re getting nowhere. Practise.
Good tools are essential to doing a great job. Tools don’t have to be expensive, some of the best tools may even be free. Automate repetitive chores. Don’t hammer a screw, aka use the right tool for the right job. Methods and practices are also tools.
Listen. Watch. Observe. Every feedback you receive is an opportunity waiting to be explored.
Enjoy and wind down
Enjoy your work. Enjoy your life. Wind down. Difficult problems take time to solve. They may be easier for others who have already solved similar problems before. Socialize with them.