Architecture-Driven Modernization
Download
1 / 39

Architecture-Driven Modernization of legacy C++ Components Ira D. Baxter, Michael Mehlich, Robert L. Akers Semantic Des - PowerPoint PPT Presentation


  • 398 Views
  • Uploaded on

Architecture-Driven Modernization of legacy C++ Components Ira D. Baxter, Michael Mehlich, Robert L. Akers Semantic Designs, Inc. 12636 Research Blvd, Suite C214 Austin, Texas 78759 [email protected] January, 2005 Overview Reengineering Massive Software requires Massive tools

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' Architecture-Driven Modernization of legacy C++ Components Ira D. Baxter, Michael Mehlich, Robert L. Akers Semantic Des' - oshin


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Slide1 l.jpg

Architecture-Driven Modernization

of legacy C++ Components

Ira D. Baxter, Michael Mehlich, Robert L. Akers

Semantic Designs, Inc.

12636 Research Blvd, Suite C214

Austin, Texas 78759

[email protected]

January, 2005


Overview l.jpg
Overview

  • Reengineering Massive Software requires Massive tools

  • DMS® Software Reengineering Toolkit

    • Program Transformations as a key technology

    • Real Transformation rules

  • Massive Transformations

    • Migrating application software to new languages

    • Architectural Restructuring of Legacy Applications


An egyptian legacy system l.jpg
An Egyptian Legacy System

30 years to build

10,000 slaves

How can we reengineer this?


Modernized l.jpg
… Modernized

Requires massive reengineering

 tools

Tools change your definition of architecture!


Software change tools need infrastructure too l.jpg
Software Change ToolsNeed Infrastructure Too

  • To build a conventional application

    • Define specifications

    • Implement application

    • Use Operating System to provide standard services

      • File/Terminal I/O, CPU management, Security

  • To build an automated software change tool

    • Define specifications

    • Implement tool

    • Use …?… to provide standard services

      • Lexing/Parsing

      • Life after Parsing: Tree/Symbol table building, Analysis management, Transformation, PrettyPrinting

  • This talk

    • DMS: a practical change-tool infrastructure

    • BMT: An application of DMS to legacy distributed system in C++


Dms software reengineering toolkit automated custom code analysis and enhancement l.jpg
DMS® Software Reengineering ToolkitAutomated, custom code analysis and enhancement

  • Enables wide variety of SE tasks to be automated

    • Source Formatters, Hyperlinked Source Browsers

    • Source code Obfuscation

    • Documentation and metrics extraction

    • Preprocessor conditional simplification

    • Test Coverage and Profiling tools

    • Clone Detection and removal

    • XML DTD compilation

    • DSL code generation: Factory Automation

    • Migration

  • Research tasks

    • Model-driven weaving (U. Alabama)

    • Architectural extraction/Multi-model consistency checking (JPL)

    • HTML cleanup (IRST/Italy)

Commercial

Applications

ICSE 2004:DMS: Program Transformationsfor Practical Scalable Software Evolution


Transformation systems l.jpg
Transformation Systems

Stepwise Semiautomatic Conversion of Specs to Code

Spec

Rqmts

Prog

Transform Engine

fS

fG

ti

Transformsaka “rules”

like-term

combination

factoring

distributive

law

unity

multiplier

remove

parentheses

t1

t2

tk-2

tk-1

tk

...

f1

fG

fS

fk-1

fk

(x-1)y+2y (xy-1y)+2y xy-y+2y xy+y (x+1)y


Expertise number of rules l.jpg
Expertise == Number of Rules

  • Mathematics

    • Novice (9th grade algebra): x+0  x

    • Amateur (HS Senior): sin^2(x)+cos^2(x)  1

    • Journeyman: (Frosh Calculus) integrals

    • Craftsman: (B.S. Math) Linear Algebra, Group Theory

    • Expert: (Ph.D. Mathematics) Category Theory, Topology, …

  • Transformation Engines

    • Toy: several rules

    • Useful: 50 rules (simplification/optimization)

    • Powerful: 250 rules (testing, code generation)

    • Indispensable: 2000 rules (massive program translation)


How to use rules knowledge metaprogram l.jpg
… + "how to use rules" knowledge= MetaProgram

  • Mathematics

    • Solve for variable, Simplification (novice)

    • Simultaneous equations

    • Change of domain (expert)

  • Transformation Engines

    • Tactic

      • Apply rules till exhaustion (useful)

    • Strategy

      • Metaprograms (sophisticated)


Software reengineering toolkit infrastruture l.jpg
Software Reengineering Toolkit Infrastruture

Symbol

Table

Compiler

Data

Structures

Source

Files

(Domain

Notation)

Revised

Source

Files

Lexer/Parser

Declarations

Unparser

Compiler

Structures

Attribute

Evaluator

Analyzers

Parser

Definition

Debug Text

Transforms

Domain

Transformation

Viewer

Definition

Engine

Reader

Procedures

Sequencing;

Transforms

Language

Descriptions

Unparser definitions

Analysis + Transform

Descriptions

= Tool definition

Languages available: C++, Java, C#, C, Ada, Fortran, XML, HTML, SQL, JavaScript, PHP, Verilog, VHDL, custom


Fundamental issue scale l.jpg
Fundamental Issue: Scale

  • Engineering hard but straightforward

    • Ugly details: C preprocessors, etc.

  • Legacy Systems are huge

    • MSLOC + tens of thousands of files

      • Careful design of hypergraph to conserve space

    • Arbitrary languages => robust parsing technology

      • Need for domain agility: fast domain/dialect definition

      • Use domain notations to define knowledge

    • Applications use multiple languages

      • reasoning and transforms must work with mix

  • Reasoning/Analysis costs

    • "Incremental" Knowledge capture => domains

    • Computers do Symbolic computation slowly => Parallel foundations

    • Future: RuleSet compilers


Knowledge capture dms parts l.jpg
Knowledge Capture:DMS Parts

Domain

  • Syntax (domain notation)

    • External Form (what you can say: string or graphical)

    • Internal Form (How DMS stores it)

    • Parser (how to convert external form to internal form)

    • PrettyPrinter (how to display the Internal Form)

  • Semantics (what the domain means)

    • Analyzers (how to analyze in the domain)

    • Optimizations (how to optimize in the domain)

    • Refinements (how to transform one domain to another


Rule specification language l.jpg
Rule Specification Language

default base domain Cpp;

rule unit_quotient(e: expression) =

“\e / \e” -> “1” if is_integral(e)

/\ no_side_effects(e).

ruleset simplify = { unit_quotient, plus_0, times_1, equal_self } + boolean_simplify.

pattern getter_method(t: typespecifier,

attribute: identifier) =

“\t \get\(\attribute\) { return \attribute; }”

with side-effect add_new_symbol(get(attribute)).

Domain Name

Quoted domain Syntax

Semantic condition

Meta function


Refinement transforms jovial to c l.jpg
Refinement transformsJovial to C

default source domain Jovial;

default target domain C;

private rule refine_data_reference_dereference_NAME

(n1:[email protected],n2:[email protected])

:data_reference->expression

= "\n1\:NAME @ \n2\:NAME" -> "\n2->\n1".

private rule refine_for_loop_letter_2

(lc:[email protected],f1:[email protected],

f2:[email protected],s:[email protected])

:statement->statement

= "FOR \lc\:loop_control :

\f1\:formula BY \f2\:formula; \s\:statement“

->

"{ int \lc = (\f1);

for(;;\lc += (\f2)) { \s } }“

if is_letter_identifier(lc).

Domain Name

Pattern Variables

Source Domain Syntax

Target Domain Syntax


Refinement transforms in action jovial to c l.jpg
Refinement Transforms in ActionJovial to C

JOVIAL Source:

FOR i: j*3 BY 2 ;

[email protected] = [email protected]+I;

Translated C Result:

{ int i = j*3;

for (;;i+=2)

{ mydata->x = mydata->x + i}

}

Typically lots of small transforms for full translation

~2500 rules to translate full Jovial


A more complex example jovial to c l.jpg
A More Complex ExampleJovial to C

START

TABLE TFP'D'TWRDET (1:109,12:37);

BEGIN

% Main status boolean %

ITEM TFP'G'TWRDET STATUS (V(YES),V(NO));

END

TYPE TFP'D'TWRDET'TABLE TABLE (7:23) W 3;

BEGIN

ITEM TFP'ITM S 3 POS(0,3); "cube axis"

END

%begin proc%

PROC PROC'A(c1) S;

BEGIN

ITEM match'count U 6;

%an item%

ITEM c1 C 5; "parameter value"

ITEM c2 C 7;

IF c1 <= c2 AND c2 > c1;

match'count = UBOUND(TFP'D'TWRDET,0) + UBOUND(TFP'D'TWRDET'TABLE,0);

"result off by 1 so adjust"

match'count = match'count+1;

BEGIN

match'count=match'count/2;

PROC'A = match'count; % return answer %

END "cleanup and exit";

END "end proc"

TERM

#include "jovial.h"

static struct

{ /* Main status boolean */

enum { V(yes$OF$tfp_g_twrdet$OF$tfp_d_twrdet),

V(no$OF$tfp_g_twrdet$OF$tfp_d_twrdet) }

tfp_g_twrdet _size_as_word;

} tfp_d_twrdet[109][26];

typedef union

{ W(3);

struct

{ POS(0, 3) S(3) tfp_itm:4 _align_to_bit; /* cube axis */

};

} tfp_d_twrdet_table[17];

static S proc_a(C(5) c1);/* begin proc */

static S proc_a(C(5) c1)

{ __typeof__(proc_a(c1)) RESULT(proc_a);

_main:

{ U(6) match_count;

C(7) c2;

if (CHARACTER_COMPARE(BYTE_CONVERT(C(7), c1, 7), c2) <= 0

&& CHARACTER_COMPARE(c2, BYTE_CONVERT(C(7), c1, 7)) > 0)

match_count = UBOUND(tfp_d_twrdet, 2, 0) + 16;

/* result off by 1 so adjust */

match_count = (S(6))match_count + 1;

{ match_count = (S(6))match_count / 2;

RESULT(proc_a) = (S(6))match_count; /* return answer */

} /* cleanup and exit */

;

}

_return:

return RESULT(proc_a);

} /* end proc */

packed tables with bit offsets,

typedefs, functions,

string operations, comments

Equivalent C

(used with hand-coded macro library)


Mda in the large a domain interconnection network l.jpg

NaturalLanguageTellers

ElectronicFundsTransfer

PunchPressControl

FighterAircraftNavigation

Specific

Applications

NaturalLanguageParsing

MoneyManagement

Real

Time

Control

Global

Navigation

Generic

Applications

refines to

Algebra

GraphicalUser

Interface

Data

Structures

Parallelism /

Distributed

Computation

Computer

Science

refines to

refines to

optimize

OOP

Logic

Functional

Data

Flow

Execution

Model

refines to

optimize

analyze to

C

Prolog

Haskell

Occam

Target

Execution

opti mize

MDA in the large:A Domain Interconnection Network


C refactoring support l.jpg

Reengineering parser

ANSI, MSVC6 C++, GCC3

Expansion-controllable preprocessor

Builds compact AST, capturing

Templates

Comments

Preprocessor directives

Source file position

Multiple files

C++ scoped name resolution

Full symbol table with types

Expression types

Conditional definitions

Accessible from transforms

Updateable from transforms

Procedural transforms

Direct AST manipulation

Cross-file transformations

Metaprogramming

Source-to-source transforms

Using C++ syntax

Attribute evaluation

Arbitrary analyzers

Callable as rule conditions

Prettyprinting regenerates

Comments

Whitespace

#includes

Can generate source browser

C++ Refactoring Support


How to modernize real code l.jpg

!

implement BMT, a practical conversion tool

How to Modernize Real Code?

Converting Legacy Components into Modern Components

Avionics Application

Legacy Bold Stroke

6000 components

3M SLOC C++

1990s

Distributed Architecture

Modern Bold Stroke

6000 components

3M SLOC C++

MoBIES architecture

“PRiSm”

?


Bmt rearchitecting distributed avionics software l.jpg
BMT: Rearchitecting distributedAvionics Software

  • Boeing BoldStroke: 6000 C++ modules

    • Avionics Mission Software (~~ 1M SLOC/plane)

      • Product Line: Used in several different military airframes

    • Distributed across multiple CPUs in airplane

    • Architected 1992

      • as components with monolithic APIs

      • use custom distributed data protocols

  • Goal: Rearchitect into more reusable parts

    • Restructure APIs into conceptually clean groups

    • Move towards CORBA/RT component model

    • Change communication to use ORBs

    • Use automated tool


Corba distributed component architecture l.jpg

facet1

receptacle1

C

o

m

p

o

n

e

n

t

facet2

receptacleK

facetN

event

sink1

event

source1

event

sinkM

CORBADistributed Component Architecture

method calls

C

o

m

p

o

n

e

n

t

X

C

o

m

p

o

n

e

n

t

A

C

o

m

p

o

n

e

n

t

Z

Facet:

offered service

Receptacle:

used service

Event Sink:

trigger

Event Source:

signal

C

o

m

p

o

n

e

n

t

B

C

o

m

p

o

n

e

n

t

Y

events

runtime wiring


Bold stroke component conversion l.jpg
Bold Stroke Component Conversion

Configuration

methods

Configuration

Facet Class

Distribution

Facet Class

Locking

methods

DMS

xform

Distribution

methods

Locking

Facet Class

Application1

Facet Class

Application

methods

Component

(Data) Class

Application2

Facet Class

Component Data

Component Representative Class

Legacy Bold Stroke

Component

(single C++ class

and support classes)

PRiSm Bold Stroke Component:

Always an Interface

(Not shown: any needed support classes)

ASPECT:

Engineer Specified

Facetization


Facet aspect specification describes desired component structure l.jpg
FACET (Aspect) SpecificationDescribes desired component structure

COMPONENT GPS

FACET GPS_State

FACET GPS_UpdateState

EVENTSINK GPS_changed

PORT EXECUTION Basic

PORT EVAPORATION Basic

PORT PERSISTANCE Basic

PORT LOCK Basic

END COMPONENT

FACET GPS_State inherit none

bool Get_Status () const;

bool IsInitDataRequested () const;

int GetDuration () const;

bool FailedStatus () const;

const result_type& Requested () const;

result_type Achieved () const;

bool ResourceOK () const;

END FACET

COMPONENT GPS

FACET GPS_State

FACET GPS_UpdateState

EVENTSINK GPS_changed

PORT EXECUTION Basic

PORT EVAPORATION Basic

PORT PERSISTANCE Basic

PORT LOCK Basic

END COMPONENT

FACET GPS_UpdateState

void Set_GPS();

void Move_GPS ();

END FACET

FACET GPS_UpdateState

void Set_GPS();

void Move_GPS ();

END FACET

PORT EXECUTION Basic (… EVENT SINK)

// Standard methods for execution need not be mentioned.

void Push (const Events& myEventSet);

END FACET

DELETED Basic // signatures in this section are removed

PushSupplier_ptr GetEventSupplierReference ();

END FACET

PERSISTANCE PORT Basic

// Standard methods for execution need not be mentioned.

void MapState (Elements& GPS_Elements);

void SetPersistenceAdapter (PersistenceAdapter& anAdapterPtr);

ACE_Lock& GetLock () const;

END FACET

PORT LOCK Basic

// The lock facet is accessible to the public.

ACE_Lock& GetLock () const;

END FACET

EVENTSINK GPS_change_changed

// Optional… only needed if standard push convention not used

void Update_GPS(Events& event);

END EVENTSINK

  • A DMS domain

  • Used to lookup methods

  • Uses C++ overload name resolution


Several kinds of subtasks l.jpg
Several kinds of subtasks

  • Creation of new classes with predetermined structure

    • facets, wrappers, EquivalentInterface

      • Drawn from facet specifications and the legacy code

    • Event sinks and receptacles

      • From legacy code fragments recognized by idiom

      • Some related legacy code to be deleted

  • Modification of reference access paths in multiple moved methods

    • in legacy classes

    • in code relocated to facets and wrappers

  • Extension and modification of name space

    • to support new and relocated code


Doing all this requires l.jpg
Doing all this requires…

  • Parsing and name and type resolution of C++ code

    • preprocessing directives

      • processed (for semantic analysis)

      • preserved (as modified source code)

  • Parsing facet specifications

    • For targeted component and all of component's neighbors

    • Looking up facet method signatures in application code

  • Constructive patterns

    • for new classes and their constituents

  • Recognizer patterns

    • for recognizing idiomatic forms

  • Rewrite rules

    • for access path modification

  • Prettyprinters to display re-engineered component

  • Sequencing code to wire these pieces together


Prism component sketch l.jpg
PRiSm Component Sketch

class a_component

{ facet1_type* facet1;

receptacle1_type *receptacle1;

data declarations… };

  • Central class

  • Facet

  • Receptacle

class a_facet

{ private: a_component* component;

component= … ; // somebody does this

public:

component_data* GetComponent()

{ return component; }

t1method1() { … component->data… } };

class a_receptable

{ private: a_component* component;

Nfacet_references int=0;

facet_type target_facet[];

public:

component* GetComponent()

{ return component; }

facet_type GetSingletonFacet()

{ return target_facet[0]; }

void AddFacet(facet_type facet)

{ target_facet[Nfacet_references++]

=facet; } };


Prism idiom as dms pattern l.jpg
PRiSm idiom as DMS pattern

ComponentEI_impldothFile(ComponentName,ApplicationFacets)

pattern ApplicationFacets(members: identifier_list)=tag.

pattern GenericComponentEI_Impldoth(ComponentName:identifier,

ApplicationFacets: tag): compilation_unit =

“\ComponentNameComment\(\ComponentName\)

#pragma once

#ifndef \ComponentHFileName\(\ComponentName\)

#define \ComponentHFileName\(\ComponentName\)

#include "GenericComponent.h"

\ApplicationFacetClassDeclarations\(\ApplicationFacets\)

class \ComponentEI_ImplName\(\ComponentName\): public GenericComponent

{ public:

// Called during first pass of the configurator

\ComponentEI_ImplName\(\ComponentName\)

(const UUIdentifier& id, // every created component has an object id

GenericComponentParameters& parameters, // and some initialization parameters

\FacetPointerArgumentDeclarations\(\ApplicationFacets\) // One for every facet:

);

  ~\ComponentEI_ImplName\(\ComponentName\)();

  virtual bool IsNil () const;

  virtual const UUIdentifier& GetId () const;

\ProvideFacetDeclarations\(\ApplicationFacets\)

protected:

// Protected Declarations... none needed for MOBIES components

private:

\ComponentEI_ImplName\(\ComponentName\)(); // parameterless constructor; NEVER CALLED

\ComponentName(const \ComponentName &right); // copy constructor; DO NOT USE

UUIdentifier id_; \\ component instance name

\FacetPtrMemberDeclarations\(\ApplicationFacets\)

};

#endif”.

The detailed truth

Used to generate

PRiSm component

instance


Rough procedural metaprogram l.jpg
Rough procedural metaprogram

For each faceted component specification

Create central class (instantiate pattern)

Populate with application data

For each specified facet

Create class for facet

Add facet data member, getter to central class

Add central class member, getter to facet class

Copy methods for facet into facet class

Modify all legacy class members accesses:

“\name ->\which_facet_class\(\name\)->\name”

For each specified receptable

Create class for receptacle

Add receptable data member, getter to central class

Add central class member, getter to receptacle class

Process other PRiSm APIs…


Bmt toy example spec l.jpg

FACETspecification

COMPONENT GPS

FACET GPS_This

FACET GPS_Other

END COMPONENT

FACET GPS_This

"GetStatus";

"ThisFacetStatus";

END FACET

FACET GPS_Other

"OtherFacetStatus";

END FACET

Not explicitly specifiedwhat to do

BMT Toy Example: Spec

Example "legacy code"

unsigned int GlobalStatus();

class GPS

{ public:

unsigned int GetStatus();

unsigned int ThisFacetStatus();

unsigned int OtherFacetStatus();

unsigned int ComponentStatus();

unsigned int status_;

};

unsigned int GPS::GetStatus()

{ return status_;

};

unsigned int GPS::ThisFacetStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

unsigned int GPS::OtherFacetStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

unsigned int GPS::ComponentStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}


Bmt toy example component l.jpg
BMT Toy Example: Component

Example "legacy code"

Resulting Component.h, ...cpp

unsigned int GlobalStatus();

class GPS

{ public:

unsigned int GetStatus();

unsigned int ThisFacetStatus();

unsigned int OtherFacetStatus();

unsigned int ComponentStatus();

unsigned int status_;

};

unsigned int GPS::GetStatus()

{ return status_;

};

unsigned int GPS::ThisFacetStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

unsigned int GPS::OtherFacetStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

unsigned int GPS::ComponentStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

/*component.h*/

#include "BM__Component/BM__Component.h"

class GPS_Component : public BM__Component

{ public:

GPS_Component(UUIdentifier componentId, class GPS_ThisFacet *GPS_ThisFacetPtr, class GPS_OtherFacet *GPS_OtherFacetPtr);

~GPS_Component();

unsigned int ComponentStatus();

class GPS_ThisFacet *GetGPS_ThisFacetPtr();

class GPS_OtherFacet *GetGPS_OtherFacetPtr();

const UUIdentifier &GetId() const;

bool IsNil() const;

private:

UUIdentifier componentId_;

class GPS_ThisFacet *GPS_ThisFacetPtr_;

class GPS_OtherFacet *GPS_OtherFacetPtr_;

};

/*component.cpp*/

GPS_Component::GPS_Component( UUIdentifier componentId, class GPS_ThisFacet *GPS_ThisFacetPtr, class GPS_OtherFacet *GPS_OtherFacetPtr) : componentId_(componentId),

GPS_ThisFacetPtr_(GPS_ThisFacetPtr),

GPS_OtherFacetPtr_(GPS_OtherFacetPtr) {}

GPS_Component::~GPS_Component() { }

unsigned int GPS_Component::ComponentStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = GPS_ThisFacetPtr_ ->ThisFacetStatus();

unsigned int tmp4 = GPS_OtherFacetPtr_ ->OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4; }

class GPS_ThisFacet *GPS_Component::GetGPS_ThisFacetPtr()

{ return GPS_ThisFacetPtr_; }

class GPS_OtherFacet *GPS_Component::GetGPS_OtherFacetPtr()

{ return GPS_OtherFacetPtr_; }

const UUIdentifier &GPS_Component::GetId() const

{ return componentId_; }

bool GPS_Component::IsNil() const

{ return (componentId_ == UUIdentifier::GetNullId());

}

FACETspecification

COMPONENT GPS

FACET GPS_This

FACET GPS_Other

END COMPONENT

FACET GPS_This

"GetStatus";

"ThisFacetStatus";

END FACET

FACET GPS_Other

"OtherFacetStatus";

END FACET

unsigned int GPS_Component::ComponentStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = GPS_ThisFacetPtr_ ->ThisFacetStatus();

unsigned int tmp4 = GPS_OtherFacetPtr_ ->OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

Not explicitly specifiedwhat to do

unsigned int GPS::ComponentStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}


Bmt toy example facet1 l.jpg
BMT Toy Example: Facet1

Example "legacy code"

Resulting ThisFacet.h, …cpp

unsigned int GlobalStatus();

class GPS

{ public:

unsigned int GetStatus();

unsigned int ThisFacetStatus();

unsigned int OtherFacetStatus();

unsigned int ComponentStatus();

unsigned int status_;

};

unsigned int GPS::GetStatus()

{ return status_;

};

unsigned int GPS::ThisFacetStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

unsigned int GPS::OtherFacetStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

unsigned int GPS::ComponentStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

/*facet.h*/

#include "BM__Component/BM__Facet.h"

class GPS_ThisFacet : public BM__Facet

{ public:

GPS_ThisFacet(const UUIdentifier &facetId, class GPS_Component *const component);

~GPS_ThisFacet();

unsigned int GetStatus();

unsigned int ThisFacetStatus();

const UUIdentifier &GetId() const;

bool IsNil() const;

private:

UUIdentifier facetId_;

class GPS_Component *component_;

};

/*facet.cpp*/

GPS_ThisFacet::GPS_ThisFacet( const UUIdentifier &facetId, class GPS_Component *const component) : facetId_(facetId), component_(component) { }

GPS_ThisFacet::~GPS_ThisFacet() {}

unsigned int GPS_ThisFacet::GetStatus()

{ return component_->status_; }

unsigned int GPS_ThisFacet::ThisFacetStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = component_ ->ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = component_ ->GetGPS_OtherFacetPtr()->OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

const UUIdentifier &GPS_ThisFacet::GetId() const

{ return facetId_; }

bool GPS_ThisFacet::IsNil() const

{ return (facetId_ == UIdentifier::GetNullId()); }

FACETspecification

COMPONENT GPS

FACET GPS_This

FACET GPS_Other

END COMPONENT

FACET GPS_This

"GetStatus";

"ThisFacetStatus";

END FACET

FACET GPS_Other

"OtherFacetStatus";

END FACET

Not explicitly specifiedwhat to do


Bmt toy example facet2 l.jpg
BMT Toy Example: Facet2

Example "legacy code"

Resulting OtherFacet.h, ...cpp

unsigned int GlobalStatus();

class GPS

{ public:

unsigned int GetStatus();

unsigned int ThisFacetStatus();

unsigned int OtherFacetStatus();

unsigned int ComponentStatus();

unsigned int status_;

};

unsigned int GPS::GetStatus()

{ return status_;

};

unsigned int GPS::ThisFacetStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

unsigned int GPS::OtherFacetStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

unsigned int GPS::ComponentStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = ComponentStatus();

unsigned int tmp3 = ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

/*facet.h*/

#include "BM__Component/BM__Facet.h"

class GPS_OtherFacet : public BM__Facet

{ public:

GPS_OtherFacet(const UUIdentifier &facetId, class GPS_Component *const component);

~GPS_OtherFacet();

unsigned int OtherFacetStatus();

const UUIdentifier &GetId() const;

bool IsNil() const;

private:

UUIdentifier facetId_;

class GPS_Component *component_;

};

/*facet.cpp*/

GPS_OtherFacet::GPS_OtherFacet( const UUIdentifier &facetId, class GPS_Component *const component) :

facetId_(facetId), component_(component) { }

GPS_OtherFacet::~GPS_OtherFacet()

{ }

unsigned int GPS_OtherFacet::OtherFacetStatus()

{ unsigned int tmp1 = GlobalStatus();

unsigned int tmp2 = component_ ->ComponentStatus();

unsigned int tmp3 = component_ ->GetGPS_ThisFacetPtr()->ThisFacetStatus();

unsigned int tmp4 = OtherFacetStatus();

return tmp1 | tmp2 | tmp3 | tmp4;

}

const UUIdentifier &GPS_OtherFacet::GetId() const

{ return facetId_; }

bool GPS_OtherFacet::IsNil() const

{ return (facetId_ == UUIdentifier::GetNullId());

}

FACETspecification

COMPONENT GPS

FACET GPS_This

FACET GPS_Other

END COMPONENT

FACET GPS_This

"GetStatus";

"ThisFacetStatus";

END FACET

FACET GPS_Other

"OtherFacetStatus";

END FACET

Not explicitly specifiedwhat to do


Bmt status l.jpg
BMT Status

  • DMS Definitions

    • Domains: C++, FACET

      • C++ parser, name resolver, prettyprinter

        • Reads 150K SLOC of MSVC6 include files

      • FACET parser, attribute evaluator to extract facets

    • Rules/Patterns: ~400

      • organized in sets ("access path update", …)

    • Metaprogram

      • Exhaustive application of rule sets

      • 11K SLOC PARLANSE code

  • Applied to multiple Boeing components

    • Currently in experimental evaluation on small set

    • Does >>90% of hand-work required


Slide34 l.jpg

(Boeing Report)Project A Code Conversionfrom ‘legacy BoldStroke component model’ to ‘PRiSm component model’

October 11, 2004


Tasks to complete wrapperized prism solution after executing bmt l.jpg
Tasks to complete “wrapperized PRiSm” solution after executing BMT

  • General

    • After BMT executes, review the updated software files for “ATTENTION_ CONVERTER” comments. This comment indicates the BMT converted a code snippet that a software engineer needs to verify for correctness.

  • Wrapper

    • After BMT executes, the Wrapper.cpp is 100% complete.

    • After BMT executes, the Wrapper.h is 100% complete.

      • Engineer modifications:

        • May be some extraneous #include files to delete.

  • Facet

    • After BMT executes, the Facet.cpp is 100% complete.

    • After BMT executes, the Facet.h is 100% complete.

      • Engineer modifications:

        • May be some extraneous #include files to delete.

  • Receptacle

    • After BMT executes, the Receptacle.cpp is 100% complete.

    • After BMT executes, the Receptacle.h is 100% complete.

      • Engineer modifications:

        • May be some extraneous #include files to delete.

  • Equivalent Interface

    • After BMT executes, the EquivalentInterface.cpp is 100% complete.

    • After BMT executes, the EquivalentInterface.h is 100% complete.

      • Engineer modifications:

        • May be some extraneous #include files to delete.


Tasks to complete wrapperized prism solution after executing bmt continued l.jpg
Tasks to complete “wrapperized PRiSm” solution after executing BMT - continued

  • Event Sink

    • After BMT executes, the EventSink.cpp is roughly 75% complete.

    • After BMT executes, the EventSink.h is roughly 90% complete.

      • Engineer modifications:

        • May be some extraneous #include files to delete in the .h files.

        • Event consumer and supplier software and Push methods were completely copied from the old classes to the EventSink classes. The converting engineer shall decide:

          • what remains

          • what code is moved back and how to implement this ‘moved back’ code

          • where to insert pointers to the old classes.

  • Legacy Classes (Component Impl)

    • After BMT executes, the Legacy.cpp is roughly 85% complete.

    • After BMT executes, the Legacy.h is roughly 100% complete.

      • Engineer modifications:

        • May be some extraneous #include files to delete in the .h files.

        • The new correct facet pointers are sometimes not initialized and sometimes missing from the legacy classes.

  • Factory

    • Engineer shall build component’s factory from scratch.

    • After BMT executes, the Factory is 0% complete.


Bmt magnitude l.jpg
BMT Magnitude executing BMT - continued

  • BMT contains ~1.5 M lines of code

    • Most of this is DMS machinery

  • BUT only ~ 13K lines are BMT specific

  •  Huge leverage of DMS infrastructure for task


Bmt user productivity l.jpg
BMT-user productivity executing BMT - continued

  • Trial component

    • Medium Sized

    • Estimated hand-conversion effort ~~ 1 man-month

    • Automated conversion time ~~ 8 minutes on 1 Ghz PC

      • Legacy classes retained in 10 source files

        • 2222 of 7347 lines of code changed

      • 34 new files

        • 2109 new lines of code and comments

  • DARPA-planned flight demo with 60+ components

    • Estimated ~~240K SLOC to modify

  • Ultimately: ~6000 components

    • BMT effort: ~~12 mm total

      • 50% time in defining conversion

    • Hand conversion: 6000 man-months


Conclusion l.jpg
Conclusion executing BMT - continued

  • Can automate architecture-driven modernization

    • Many possible custom reengineering possibilities

    • A key technology for software quality improvement

  • Need generalized compiler-like infrastructure to amortize tool engineering costs

    • Definable parsers, prettyprinters, transforms

    • Must scale to application systems with MSLOCs

  • DMS provides these capabilities

    • growing infrastructure and standard language modules

    • Milestone: usable on C++!!

    • Knowledge capture as domains

    • Mechanical basic for MDA in the large

      www.semanticdesigns.com


ad