Table of Contents
The objective is to create an application to manage a set of multimedia files in our computer. With this application, we will be able to store different information about those files. As we are focusing on audio and video files, there will be some features that are common to both file types, but there will also be some features that are specific of each type (such as, for instance, the size of the video screen).
A MultimediaObjectException
class is going to be used to handle errors. Whenever a MultimediaObjectException
happens, the program must display the following message in the screen (when it is caught):
Incorrect value
MultimediaObject
classConsidering that there is a series of common features to all multimedia files, a parent class, called MultimediaObject
, is going to be defined, containing the following items:
Definition of the following attributes: name
, to store the name of the file, and minutes
and seconds
, to hold the length of the multimedia file in minutes and seconds, respectively.
A constructor to be passed the necessary values to initialize those attributes. The constructor will check that the initialization value for seconds
is greater or equal to 0 and lower than 60, and that the value for minutes
is greater or equal to 0. Otherwise, a MultimediaObjectException
exception must be thrown.
A printData()
method to print on the screen all the attribute data:
File: name_of_the_file Length: minutes:seconds
For instance:
File: Nothing else matters.mp3 Length: 6:15
Now we are going to define the classes to differentiate between audio and video files. These classes extend from MultimediaObject
class.
The class in charge of modeling audio files, called AudioObject
, must contain:
Definition of the bitRate
, frequency
and quality
attributes. The first two store integer values, whereas the last one will be a String equal to Stereo
or Mono
.
Constructor to initialize all attributes that an AudioObject
can hold and also checks that the bit rate and frequency are initialized to values greater or equal to 0 and the quality is equal to any of the two allowed values. Otherwise, the MultimediaObjectException
exception must be thrown.
A printData()
method that invokes the method in te parent class and also displays the values of the attributes of the child classed, in the format:
Bit rate: value in kbps Frequency: value in Hz Quality: value
At the end of Section 4, there is an example of the expected output in the screen after a call to this method.
In addition, the VideoObject
class will include:
Definition of the width
, height
and fps
(frames per second) attributes. The first two are integer and the last one is a float.
Constructor with the same functionality as the constructor of AudioObject
.
Similarly, a printData()
method that, after invoking the method in the parent class, shows the following data in the screen:
Screen size: width x height Frames per second: value
Finally you are going to implement a program that manipulates these elements. This program will be modeled by the MultimediaCollection
class. This program must create two MultimediaObject
objects: one AudioObject
and one VideoObject
. The values of these files are:
AudioObject:
VideoObject:
Once created, their information must be displayed on the screen. The result will be similar to:
File: Nothing else matters.mp3 Length: 6:15 Bit rate: 192 kbps Frequency: 44100 Hz Quality: Estéreo File: Kill Bill Trailer.mpg Length: 3:15 Screen size: 176 x 76 Frames per second: 30.0
Your program must handle all the exception that can be thrown, showing the corresponding error message on the screen. The exception block must differentiate between MultimediaObjectException
and the rest of exceptions.
The solution is included in the following listing:
public class MultimediaObjectException extends Exception { public MultimediaObjectException() { super("Incorrect value"); } }
public class MultimediaObject { String name; int minutes; int seconds; public MultimediaObject(String name, int minutes, int seconds) throws MultimediaObjectException { this.name = name; if (minutes >= 0) { this.minutes = minutes; } else { throw new MultimediaObjectException(); } if (seconds >= 0 && seconds < 60) { this.seconds = seconds; } else { throw new MultimediaObjectException(); } } public void printData() { System.out.println("File: " + name); System.out.println("Length: " + minutes + ":" + seconds); } }
public class AudioObject extends MultimediaObject { int bitRate; int frequency; String quality; public AudioObject(String name, int minutes, int seconds, int bitRate, int frequency, String quality) throws MultimediaObjectException { super(name, minutes, seconds); if (bitRate >= 0) { this.bitRate = bitRate; } else { throw new MultimediaObjectException(); } if (frequency >= 0) { this.frequency = frequency; } else { throw new MultimediaObjectException(); } if (quality.equalsIgnoreCase("Stereo") || quality.equalsIgnoreCase("Mono")) { this.quality = quality; } else { throw new MultimediaObjectException(); } } public void printData() { super.printData(); System.out.println("Bit rate: " + bitRate + " kbps"); System.out.println("Frequency: " + frequency + " Hz"); System.out.println("Quality: " + quality); } }
public class VideoObject extends MultimediaObject { int width; int height; float fps; public VideoObject(String name, int minutes, int seconds, int width, int height, float fps) throws MultimediaObjectException { super(name, minutes, seconds); if (width >= 0) { this.width = width; } else { throw new MultimediaObjectException(); } if (height >= 0) { this.height = height; } else { throw new MultimediaObjectException(); } if (fps >= 0) { this.fps = fps; } else { throw new MultimediaObjectException(); } } public void printData() { super.printData(); System.out.println("Screen size: " + width + " x " + height); System.out.println("Frames per second: " + fps); } }
public class MultimediaCollection { public static void main(String args[]) { try { MultimediaObject audio = new AudioObject("Nothing else matters.mp3", 6, 15, 128, 44100, "Stereo"); MultimediaObject video = new VideoObject("Kill Bill Trailer.mpg", 3, 15, 176, 76, 30.0f); audio.printData(); video.printData(); } catch (MultimediaObjectException moe) { System.err.println(moe.toString()); } catch (Exception e) { System.err.println(e.toString()); } } }
Current multitask operating systems allow the concurrent execution (i.e., at the same time) of several programs. To do so, the operating system kernel has a module called "scheduler" that, according to a series of settings, selects which is the next program to be executed next.
All programs that can be run within a multitask operating system have the following features:
An identifier of String type that allows to differentiate among programs.
A priority value with which the scheduler will decide which is the program to be run next. The priority value can be 3, 2 or 1, being 3 the highest priority and 1 the lowest priority.
All of them have a method to show the information about their identifier and priority in the screen.
The class that models these object is called Program
and stores the previous attributes, access methods for these attributes, a constructor that allows to initialize their values, and a void print()
method to show the information in the screen.
In addition, there are two special type of programs: real time programs, which always have the highest priority (value of 4), and background programs, which have the lowest priority (0). Moreover, these programs specialize the behaviour of the print
method, adding the type of program they are (real time or background).
You are asked to implement the set of classes (Program
, RealTimeProgram
, BackgroundProgram
) that model the previously described behaviour.
You must implement a Scheduler
class ("planificador" in Spanish) that is able to manage programs with different priorities. The class will have an attribute that stores an array of Program
objects, which holds the programs to schedule. The constructor of the class receives the maximum number of programs that the scheduler will be able to manage.
You are also required to implement a method able to store programs sorted by ascending priority value: void add(Program program) throws Exception
. This method must throw an exception if no more programs can be added (if the array is full).
next()
methodImplement a method in the scheduler that returns the next program to be run (the one with the highest priority among the stored programs): Program next() throws Exception
. The method will throw an exception if there is no program (the array is empty).
Note: You are free to decide what to do when there are several programs with the same priority.
The solution is included in the following listing:
public class Program { private String id; private int priority; public Program(String id, int priority) { this.id = id; this.priority = priority; } // Program public int getPriority() { return priority; } // getPriority public void print() { System.out.println("Id: " + id); System.out.println("Priority: " + priority); } // print } // Program
public class RealTimeProgram extends Program { final static int MAX_PRIORITY = 4; public RealTimeProgram(String id) { super(id, MAX_PRIORITY); } // RealTimeProgram public void print() { System.out.println("Real Time Program"); super.print(); } // print } // RealTimeProgram
public class BackgroundProgram extends Program { final static int MIN_PRIORITY = 0; public BackgroundProgram(String id) { super(id, MIN_PRIORITY); } // BackgroundProgram public void print() { System.out.println("Background Program"); super.print(); } // print } // BackgroundProgram
public class Scheduler { private Program programs[]; public Scheduler(int size) { programs = new Program[size]; } // Scheduler /** Adds a program, sorted from low to high priority */ public void add(Program program) throws Exception { boolean found = false; int i = 0; int size = programs.length; int currentPriority = program.getPriority(); // Find a place to insert into while ((!found) && (i < size)) { if (programs[i] == null) { found = true; } else if (currentPriority < programs[i].getPriority()) { found = true; } else { i++; } } // while if (found) { // Insert the program into the null position if (programs[i] == null) { programs[i] = program; } else { // Move the elements... // ...but what if it is full? if (programs[size - 1] != null) { throw new Exception("List is full (Cond 1)"); } else { // Move from the end for (int j = size - 1; j > i; j--) { programs[j] = programs[j - 1]; } // Then, asign the value programs[i] = program; } } } else { throw new Exception("List is full (Cond 2)"); } } // add public Program next() throws Exception { boolean found = false; int size = programs.length; int i = size - 1; while ((!found) && (i >= 0)) { found = (programs[i] != null); i--; } if (!found) { throw new Exception("Empty list, no program to execute"); } else { return programs[i + 1]; } } // next } // Scheduler
public class Programs { public static void main(String args[]) { Scheduler miScheduler = new Scheduler(6); try { Program program = new Program("1", 1); miScheduler.add(program); program = new Program("2", 2); miScheduler.add(program); program = new Program("3", 3); miScheduler.add(program); program = new Program("4", 2); miScheduler.add(program); RealTimeProgram realtimeProgram = new RealTimeProgram("5"); miScheduler.add(realtimeProgram); BackgroundProgram backgroundProgram = new BackgroundProgram("6"); miScheduler.add(backgroundProgram); // Test the full list (Cond 2) // miScheduler.add(new Program("7", 7)); Program next = miScheduler.next(); next.print(); } catch (Exception ex) { System.out.println(ex.getMessage()); } System.out.println("End"); } // main } // Programs