There is a singleton ConstraintMgr returned by "getConstraintMgr()" method on DataObject. This particular ConstraintMgr instance is in charge of handling input constraints on DataObjects.
This means if, at the start of the program, you create a couple of Constraint Objects and add them to the DataObject ConstraintMgr, then from that point on, attempts to set the properties to values violating the constraints (through the method setProperty(propertyname)) will fail, and a result of false will be returned from the setProperty method.
So in effect, you are prevented from setting the DataObject's properties if it violates constraints set in that constraintMgr.
However, Constraints and ConstraintMgr are reusable classes. You don't need to use the ConstraintMgr returned by DataObject.
You can create another ConstraintMgr object which contains a set of the constraints you wish to impose, and then check if a particular object satisfies it with the "satisfies" method on ConstraintMgr.
For this assignment, I imagined that you would read in each object, then check whether it satisfied a set of constraints that you created for that class, before adding it to the playlist. This way, the result playlist would only have a subset of the MP3 files that are in your filesystem, only those which satisfied the constraints.
In effect, you are querying the file system for a set of songs which satisfy the constraints.
But if you design this well, you will be able to use the same mechanism for querying the playlists in memory, or in a database, whatever.