An Introduction
to Managing Projects
With Developer/2000
An Oracle White Paper
October 1996
For developers working in large, complex projects,
managing the files that comprise those projects is
inevitably a difficult and time consuming task. Managing
files contributes nothing to productivity, yet it is a
necessary part of the development process. This is no
less true of projects built using Developer/2000 than it
is of other environments.
A typical Developer/2000 project might consist of tens or
hundreds of files, and the largest projects might consist
of thousands. These files will be of many different
types, for example:
· Forms documents and their corresponding
executables
· Reports documents
· Graphics documents
· PL/SQL libraries
· Icons and bitmaps
· DLLs built from C source files
· Text documents such as test scripts and
specifications
· Test data
· SQL scripts
and many more. The developer faced with these files
must constantly ask herself questions such as:
· What files make up this project?
· How do files depend on each other?
· Which files have been modified and need to be
recompiled?
· Which files are to be delivered to the deployment
environment?
· What type of file is this, and how do I print,
edit or compile it?
Many developer hours are wasted trying to resolve such
issues of configuration and management. Project Builder
brings these tasks under control as an integral part of
the Developer/2000 product.
Introducing Project Builder
Project Builder, introduced with Developer/2000 Release
2.0, aims to simplify the task of answering these
questions. It does so by providing the developer with a
lightweight, flexible, yet powerful tool that provides:
· A graphical presentation of a project in a
familiar "navigator" or "explorer"
style that can be viewed by file type or by dependency.
The developer can easily add, remove, locate and edit the
files that make up her project.
· A visual representation of the relationships
between the files that make up a project. The developer
can immediately see the dependencies between, for
example, PL/SQL libraries and a form document that calls
them, and use those dependencies to ensure that
executables are always up to date.
· A totally customizable environment that can be
tightly integrated with other development tools such as
version control, CASE, or project scheduling. The
developer can add new file types, defining actions such
as "edit" or "compile" for those file
types, and customize existing ones, by adding new actions
and modifying existing ones.
Figure 1. The Project Builder navigator in
Dependency view
Through its extensive customizability, Project Builder
provides a point of integration for all the development
lifecycle tasks from design to delivery. Furthermore,
because Project Builder tracks dependencies between
files, a single menu command is sufficient to ask Project
Builder to "rebuild" or "make" a
project, recompiling only those files that have changed
(or whose dependencies have changed), and automatically
applying the correct compilers to build each different
type of file.
Project Builder Terminology
To understand Project Builder, we first need to
understand some terminology. Project Builders
navigator tree contains types, connections, projects and
entries (see figure 1). Types have properties, actions
and macros.
Types
A type is the basis of every entry, and controls the
actions that are available in Project Builder. A type
determines what actions (see below) can be performed
against a file, such as edit or compile. Many types are
predefined for common kinds of files such as Forms
documents (FMB), text files and C source files.
Connections
In a typical project the developer has a number of
databases that he works against. For example, there might
be a small "scratch" database where the
developer can create any test data he needs; a large test
database that contains the data for a formal test suite;
and perhaps databases running different versions of
Oracle to test backward compatibility or new features.
Project Builder allows the developer to define and save
the connect strings associated with these various
databases, and then easily associate those connections
with the projects files, simply by dragging a
connection and dropping it on the entry for the file. For
example, referring again to figure 1, simply pick up the
connection called Personal Oracle7 and drag it to the
form Storproc.fmb; now when the Form document is next
opened from Project Builder, Form Builder will
automatically connect to the database before opening the
form.
Projects
A collection of component files that a developer is
working on is organized into one or more projects. A
project can be subdivided into subprojects if that is
more convenient for the developer. In figure 1, the
project "Benefits and Features" has been
divided into "Forms" and "Media".
Often, the organization into subprojects will mirror the
organization of the files into subdirectories, but this
is not a requirement (although it is often more
convenient for the developer).
Entries
The components that make up a project are known as
entries. An entry is simply a description of a file that
is part of a project. The definition of an entry can be
seen in a property palette (figure 2). The definition
includes general information about the file, such as its
type, its location in the file system, its size, and when
it was last modified. The actions and macros (see below)
available for the entry can also be seen.
It is important to remember that an entry is not the file
itself; rather it is a description of the file. So when
you delete an entry from a project, you are simply
telling Project Builder that the file is not part of that
project any longer. The file itself, referenced by that
entry, of course is not deleted.
Actions
An action is a command string that applies to entries,
such as print, edit or compile. The same action can be
defined for many different file types, potentially with a
different definition for each. For example, most types
have an "Edit" action defined. For a text file
type this might be defined to open the file in Notepad or
Write; for a Form document it would open it in Form
Builder. Actions can act on individual entries one at a
time (for example, print) or on several entries together
(for example, to create a Zip or tar archive).
In figure 2, the actions defined for a bitmap are shown.
All of these actions are inherited from the type (as
shown by the arrow icon).
Actions are normally defined as part of a type
definition, but the developer can also add actions to a
project or subproject; these actions are then inherited
by every entry in the project. Actions can even be added
directly to a specific entry, in which case they apply
only to that entry. Inherited actions can also be
overridden at each level of the hierarchy, as we will see
later.
Some actions, notably Build and Deliver, have a special
meaning for Project Builder and we will return to them
later.
Macro
A macro is a kind of variable defined within Project
Builder that can be used to customize and extend actions.
Just as you might use environment variables in scripts or
batch files to allow you to conveniently modify a
scripts actions without editing the script itself,
so you can use macros to customize actions without having
to edit the actions themselves. For example, you might
define a macro to determine whether to compile your
application in Debug mode or Optimized mode. To switch
off debug in preparation for building the deployment
version of the application, you would simply change one
macro definition, rather than having to find and modify
every type whose Build command made use of the Debug
flag.
There are several pre-defined macros in Project Builder,
such as the name and location of the file, and you can
add new macros as you need them. Just as for actions,
macros can be defined for types, projects and individual
entries, and are inherited in the same way.
Figure 2. The Property Palette
The Project Builder User Interface
Project Builder has three main components to its user
interface: the project navigator, the property palette
and the launcher toolbar. The first two of these will be
immediately familiar to any user who is familiar with the
other components of Developer/2000.
The Project Navigator
The Project Navigator was briefly introduced earlier.
This is the main window for managing and organizing the
entries in a project. You also launch actions against
entries from here: simply select the entry, click the
right mouse button, and the actions available are shown
in the popup menu (figure 3).
Figure 3. Example actions available on the popup menu
The navigator can be displayed in one of two views,
Project view and Dependency view.
Project View
In this view, the entries in a project are organized by
project and subproject, then by type. This is useful to
see all of the entries of a particular type, for example
all of the PL/SQL libraries, used in a project.
Dependency View
In this view, the entries in a project are organized by
dependencies between files; for example, an object file
depends on a source file and a number of header files. We
will describe below how those dependencies are
determined, and how Project Builder exploits them.
The Property Palette
In figure 2, an example of a property palette is shown.
The property palette is common to all of the
Developer/2000 tools. Project Builder has property
palettes for connections, types, entries and projects. In
the property palette the user can view and modify the
properties, actions and macros. The user can also add new
actions and macros to types, entries and projects.
Inheritance in Project Builder
The property palette shows not only the properties,
actions and macros, but also whether they are inherited
or overridden. An entry inherits properties, actions and
macros both from its type and from its project.
· An entry inherits from its type the properties,
actions and macros associated with that type.
These include properties such as whether the file is text
or binary and the actions to edit or compile an entry of
that type.
· An entry also inherits properties, actions and
macros from the project.
Properties inherited from the project include the Author
of an entry. If actions or macros are added to the
project, they are inherited by all entries in the
project.
Some properties, actions and macros can be inherited from
both the project and the type. In this case, setting the
value at the project level overrides the type.
There are also two "generic" types: <Any
File>, whose properties, actions and macros are
inherited by every type and so by every entry, and Text
File, whose properties, actions and macros are inherited
by every type whose File Contents property is set to Text
rather than Binary.
These two generic types allow a property such as Version
Control File or an action such as the editor for all
textual files to be easily set across many types without
having to define it individually for each type.
The Launcher
The toolbar that appears at the top of the Project
Builder navigator is known as the launcher. It can be
customized to provide immediate access to the tools and
editors that you use most often. This toolbar can include
"group" items that cascade to provide access to
more tools, much like the Start menu in Windows95.
Building and Delivering Projects in Project
Builder
The aim of Project Builder is not merely to provide a
graphical tool that allows the developer to locate,
organize, and edit the files that make up a project. The
greatest benefits of using Project Builder will be
realized when you use its ability to build and deliver
projects.
Dependencies and Building Projects
Tracking dependencies is one of the most complex and time
consuming tasks in any development environment.
Determining which files depend on which others is crucial
to determining when files need to be recompiled as the
result of a change. It is also the key to managing the
impact of changes; for example, if a library changes,
which forms might be affected?
Figure 4. Dependency view and implied items
Standalone tools for building (or making)
projects are available, but they are often difficult to
use or integrate with other development tools. The
scripts required by textual tools such as make are
complex and difficult to interpret, and even graphical
tools must be kept in synchronization with the other
tools in the project environment. For example, whenever
you add a file to the project you must also remember to
add it to the make script.
Project Builder provides two major advantages over such
tools:
· Dependencies can be seen directly and managed
easily in the navigator; no scripting or expertise is
required
· Dependency information is an integral part of the
project environment; there is no need to maintain
separate project information and dependency information
With this visual, integrated management of dependencies,
Project Builder makes it easy to assess the impact of
changes and to rebuild affected modules. Project Builder
greatly simplifies the tasks of ensuring that you are
always working with up to date executables, avoiding
misconfiguration problems, and delivering the right set
of files to the end user.
Implicit Dependencies
Project Builder automatically deduces many dependencies
from the Deliverable Type property and the Build action
of an entrys type. In figure 4, the developer has
added a Form document (FMB) called Storproc.Fmb to the
project. FMB files have a Deliverable Type of Forms
executable (FMX), so Project Builder automatically
adds Storproc.Fmx to the project and shows that the FMX
file is dependent on the FMB: if the FMB changes, it will
be necessary to recreate the FMX using the Build action
defined for the FMX. Notice that the implicit entry,
Storproc.Fmx, is distinguished in the navigator by a
lighter typeface.
The second file that the developer added was a Forms text
file (FMT) called Dsktest.Fmt. The Deliverable Type for
an FMT file is also Forms executable (FMX): the
Deliverable Type tells Project Builder the type of file
that, ultimately, is built for delivery to the end user.
In this case Project Builder adds the FMX and
automatically discovers the two steps necessary to reach
an FMX from an FMT by examining the Build action defined
for each type: the Build action for an FMX is to compile
the corresponding FMB, and the Build action for an FMB is
to convert from an FMT. Project Builder therefore adds
two implicit entries, Dsktest.Fmb and Dsktest.Fmx.
Project Builder can follow a chain of Build commands for
as many steps as necessary to connect an entry to its
final deliverable. (If more than one possible chain
exists, it will find the shortest).
Manual Dependencies
Sometimes, you will have dependencies that cannot be
determined automatically by Project Builder. For
instance, your form may contain calls to program units in
a PL/SQL library. If the interfaces to the program units
in the library change, it will be necessary to rebuild
the FMX.
To allow the developer to include such dependencies in
the project definition, dependencies can be added
manually. In figure 4, to indicate that Storproc.Fmx
depends on a PL/SQL library called Navigate.Pll, as shown
in figure 4, the developer selects the entry Storproc.Fmx
then clicks Add Files from the menu or toolbar. The files
chosen in the Add Files dialog that appears are then
added as dependencies of the selected entry.
Notice that the dependency is added to the FMX, not to
the FMB, as you might at first sight expect. Although the
FMB contains the calls to the PL/SQL, and therefore the
FMB will need to be recompiled, it is important to
remember that dependencies tell Project Builder what
target needs to be built, rather than what source needs
to be recompiled. From one point of view, the FMB
compiles to the FMX, but in Project Builder terms we say
that the FMX is built from the FMB, the library, and any
other dependencies we might add. Expressed in this way,
it is much clearer that when any of the dependencies
change, the FMX must be rebuilt.
Building Projects
One of the most tedious tasks in managing a project is
ensuring that the build is up to date: that
everything that needs to be rebuilt, has indeed been
rebuilt. It is rarely an acceptable solution to
constantly rebuild everything.
With Project Builder, this process is greatly simplified.
When you click the Compile Incremental command from
Project Builders menu or the corresponding toolbar
button, Project Builder determines from the dependency
information which entries need to be built and the
correct order to build them. Project Builder will examine
the file timestamps of each entry and its dependencies to
determine which files have been modified, and only
rebuild those entries which are out of date. Project
Builder determines the correct Build command to apply to
each entry from the Build action defined for that entry.
You can also click Compile All if for any reason you want
to force a rebuild of all the files in a project, or
Compile Selection to rebuild particular entries.
Deploying Projects
Once a project is completed the remaining task is to
deliver the executable files, help files, supporting
media (such as sounds, images, videos or icons) and any
other files that the end user will need to have
installed. Typically, the delivery process involves
creating an archive or "stage" of the required
files. To simplify this task, Project Builder includes a
property Deliver file which allows you to indicate which
entries represent files to be delivered, or deployed, to
the end user.
Usually the Deliver file property fill be inherited from
the type, but for some files this may not be appropriate.
In this case you can simply override the setting on
individual entries, as with any other property.
Alternatively, you might choose to organize all the
deliverables into a separate subproject, then set Deliver
file to Yes on that subproject, which will then be
inherited by all the files in the subproject.
To deliver the project, simply click
File->Adminstration->Deliver on the menu. Project
Builder will apply the appropriate Package for delivery
action to each file. These actions will usually be
defined to accept "multiple files"; for
example, if many entries have PkZip defined as the
action, you normally dont want to run PkZip once
for each file. Instead, Project Builder runs PkZip once,
passing all of the files to it at one go.
Team Development with Project Builder
In many cases you will want to use Project Builder in a
team environment, so that many developers can be working
together on the many files that make up a project. If one
developer modifies a library that another depends on, you
will want Project Builders dependency management to
track that dependency, just as it would for a single
user. In order to successfully use Project Builder in a
team environment, it is necessary to understand a little
of how Project Builder stores and shares information.
Project Builder makes use of three kinds of files, called
registries, to store information: the Global Registry,
the User Registry, and Project Registries. (In fact,
Project Registries are simply what we have been calling
Projects up to this point.) The contents of all three of
these are visible in the navigator. To ensure that these
registries remain consistent between developers, normally
one member of the team will take on the role of Project
Administrator.
The Global Registry
Commonly, the Global Registry will be shared by all
developers. It contains the type definitions that are
shared across the network. To make it accessible to
everybody, the project administrator may place it on a
shared network drive. Because this registry is shared by
the whole team, to avoid conflicting changes only the
Project Administrator should make changes to it. The
recommended way to ensure this is to use the network file
systems file permissions and access control to
ensure that, although the whole team can read this file,
only the project administrator can modify it.
(You might ask why Project Builder itself does not
provide some mechanism of its own to protect the Global
registry from conflicting updates. The answer is simply
that if the file is not protected at the level of the
network file system, then any "internal"
scheme, however clever it might be, can be subverted by
any developer who creates and copies another registry
file over the top of the Global Registry. So the registry
file should always be protected at the file system level
anyway, and once the file is protected in the file
system, an internal mechanism would be redundant.
Furthermore, by relying on the network file system for
protection, we also allow you to use whatever network
file system you choose; we do not impose a scheme that
might not be supported by particular network file
systems.)
Locking the Global Registry
Whenever the Project Administrator is making changes to
the Global Registry, the registry file is briefly locked,
to ensure that other users do not inadvertently read
inconsistent information. Normally these locks are
released so quickly that other users will be completely
unaware of their existence.
Occasionally, however, perhaps due to a very busy
network, the Global Registry will be locked just at the
instant when another user needs to read it (for example,
at startup). Project Builder will automatically retry
reading the Global Registry, but if it still cannot
succeed, the user will then see a dialog explaining that
the Global Registry is unavailable. Clicking the Retry
button will usually be sufficient to continue - unless
the Project Administrator or the network is extremely
busy!
Project Builder will repeatedly offer the option to Retry
until the file becomes available. Very occasionally,
perhaps due to a network server being down, Project
Builder will not be able to read the Global Registry even
after several clicks on the Retry button. In such a case
the user is best advised to click the Exit button and try
again later when the Global Registry is available.
Because the Global Registry contains the basic
information about types, Project Builder cannot work
without it.
The User Registry
As its name suggests, the User Registry is private to
each individual user, and it will normally be placed
either on a local drive on each users PC, or on a
private directory on a network drive. (Under Unix it is
placed under the users home directory).
Because each user has their own User Registry, they can
edit it freely, for example to add private types or to
override the definitions of types in the Global Registry.
If the User Registry is placed on a network drive, there
is, as with the Global Registry, the risk that the file
may be unavailable due to network problems. As with the
Global Registry, you will not be able to run Project
Builder if the User Registry is unavailable due to a
network failure.
Project Registries
Projects are each stored in their own Project Registry
file. Projects may be private to an individual developer,
or shared among several.
If a project is shared, the Project Administrator may
decide to provide each developer with a private copy of
the Project registry, or they may share a single copy via
a shared network drive. The best choice depends on
whether all or only one developer is allowed to modify
the project.
(Note that we are talking here about modifying the
project itself; that is, adding and removing entries, or
changing properties, actions or macros of an entry. All
users may modify the files that the entries point to,
just as if they were accessing the files directly through
the file system rather than through Project Builder).
If only one developer is allowed to modify a particular
project, the simplest approach is to place the Project
Registry on a file server, and protect the file against
update in the same way as for the Global Registry.
If more than one user is allowed to modify a project, the
recommended way to share these changes is for the project
administrator to provide each user with a private copy of
the project. The users individual changes can then
be shared using Project Builders export and import
commands.
In some cases the project administrator may decide to
share a Project Registry and allow more than one user to
update it. Although this is permitted by Project Builder,
it can be a risky strategy if many developers attempt to
update the same project: sometimes a developer will not
be able to save changes to the project. If a developer
attempts to change a project, adding an entry for
example, Project Builder will first check whether the
project has changed since it was last read; if it has
changed, Project Builder will notify the developer that
his changes cannot be saved, and will reread the latest
version of the project. The developer can then attempt to
make his changes again. Project Builder will never
overwrite one developers changes with
anothers, avoiding "last write wins"
problems. If your change is accepted by Project Builder,
you can be confident that nobody will overwrite it
without seeing your change. (This is directly analogous
to what happens when two users of a database application
attempt to update the same record in a RDBMS: the first
to update commits successfully, the second must query an
up-to-date version of the record before he can make
changes).
As with the Global and User Registries, there will be
occasions when Project Builder cannot open a particular
project. Unlike the case of those two registries,
however, this is not a severe problem. Project Builder
will simply notify the developer and continue. The
developer can work in any other open project, and attempt
to reopen the project at some later time.
Summary
Project Builder is a significant addition to the
Developer/2000 products capabilities. It provides
an easy-to-use, graphical environment for the management
of projects that simplifies development and delivery of
both simple and complex projects. It is equally suitable
for the individual developer as for the team. The
extensive customizability makes it simple to integrate
Project Builder with all the other tools that comprise
the development environment.
|