Növekményes projektösszeépítők

A növekményes projektösszeépítő egy objektum, amely egy adott módon kezeli a projekt erőforrásait. A növekményes projektösszeépítők gyakran alkalmaznak egy átalakítást az erőforráson egy erőforrás vagy más típusú termék előállításához.

A bedolgozók növekményes projektösszeépítőket biztosítanak a platformhoz a speciális erőforrás-átalakítások megvalósításához. A Java fejlesztőeszközök (JDT) például megadnak egy növekményes projektösszeépítőt, amely lefordítja a Java forrásfájlt az osztályfájlra, amikor a fájl hozzáadásra vagy módosításra kerül a Java projektben. Nyomonköveti a függő fájlokat és szükség esetén lefordítja őket.

Az API szemszögéből a platform két alaptípusú összeépítést ad meg:

A növekményes összeépítések az erőforrás-változásra épül. A változás tükrözi az összes erőforrás-módosítás hálózati hatását, mióta az összeépítő utoljára létrehozta a projektet. A delta hasonlít az erőforrásmódosítási eseményekben használttal.

A felhasználók a projekteket rendszeres időközönként kiüríthetik a projekt következő növekményes összeépítésekor a teljes projekt újraépítésének érdekében. A projekt kiürítése eltávolítja az összeépítési információkat, mint például a problémajelzők vagy osztályfájlok.

Az összeépítők legjobban egy példán keresztül érthetők meg. A JDT Java fordítót egy Java növekményes projektösszeépítő vezérli, amely lefordítja a módosított projektfájlokat. Teljes összeépítés aktiválásakor (vagy kiürítés utáni növekményes összeépítéskor) a projekt összes .java fájlja lefordításra kerül. A fordítási problémák problémajelzőként kerülnek hozzáadásra a .java fájlokhoz. Növekményes összeépítés aktiválásakor az összeépítő szelektíven lefordítja a hozzáadott, módosított vagy másképpen befolyásolt .java fájlokat, amelyek leírásra kerülnek az erőforrásváltozásokban és szükség szerint frissíti a problémajelzőket. A már nem megfelelő .class fájlok vagy jelzők eltávolításra kerülnek.

A növekményes összeépítésnek nyilvánvaló teljesítményelőnyei vannak a többszáz vagy többezer erőforrással rendelkező projekt esetén, amelyek nagy része nincs módosítva egy tetszőleges időpontban.

A növekményes összeépítés technikai problémája annak meghatározása, hogy pontosan mit kell újból összeépíteni. A Java összeépítő által karbantartott belső állapot például olyan dolgokat tartalmaz, mint a függőségi gráf és a jelentett fordítási problémák. Ezt az információt a növekményes összeépítés használja annak azonosításához, hogy mely osztályokat kell újrafordítani a Java erőforrás módosításakor.

Az összeépítés alap struktúrája a platformban van megadva, a valós munka pedig az összeépítőkódban történik. Az összetett növekményes összeépítők megvalósításának mintái túlmutatnak ezen a leíráson, mivel a megvalósítás független az adott összeépítő-kialakítástól.

Összeépítés meghívása

Az összeépítő explicit módon meghívható az alábbiak szerint:

Gyakorlatban a munkaterület-felhasználó aktivál egy összeépítést az erőforrásnavigátor-menü megfelelő parancsainak kiválasztásával.

A növekményes projektösszeépítőket a platform implicit módon is meghívja az automatikus összeépítés során. Ha engedélyezve van, akkor az automatikus összeépítések a munkaterület módosításakor futnak.

Növekményes projektösszeépítő létrehozása

Az org.eclipse.core.resources.builders kiterjesztési pont egy növekményes projektösszeépítőt biztosít a platformhoz. Az alábbi leírónyelv megjeleníti, hogy az elképzelt com.example.builders bedolgozó hogyan hoz létre egy növekményes projektösszeépítőt.

   <extension
      id="mybuilder" name="My Sample Builder" point="org.eclipse.core.resources.builders">
      <builder
         <run 
            class="com.example.builders.BuilderExample">
            <parameter name="optimize" value="true" />
            <parameter name="comment" value="Builder comment" />
         </run>
      </builder>
   </extension>

A kiterjesztési pontban azonosított osztálynak ki kell terjesztenie az IncrementalProjectBuilder platformosztályt.

   public class BuilderExample extends IncrementalProjectBuilder {
      IProject[] build(int kind, Map args, IProgressMonitor monitor)
         throws CoreException {
         // logika megadása
      return null;
      }
      protected void startupOnInitialize() {
         // inicializálás
      }
      protected void clean(IProgressMonitor monitor) {
         // összeépítő kiürítési logika megadása
      }
   }

Az összeépítés-feldolgozás a build() metódussal kezdődik, amely a kért összeépítés típusáról tartalmaz információkat. Az összeépítés az alábbi értékek egyikével rendelkezhet:

Egy növekményes összeépítés kérésekor a rendszer egy erőforrás-változást biztosít az erőforrásban az utolsó összeépítés óta történt módosítások leírása érdekében. Az alábbi részlet tovább finomítja a build() metódust.

      protected IProject[] build(int kind, Map args, IProgressMonitor monitor
         throws CoreException {
      if (kind == IncrementalProjectBuilder.FULL_BUILD) {
            fullBuild(monitor);
         } else {
         IResourceDelta delta = getDelta(getProject());
         if (delta == null) {
            fullBuild(monitor);
         } else {
            incrementalBuild(delta, monitor);
         }
      }
      return null;
   }

Néha előfordul, hogy az "X" projekt összeépítésekor az összeépítőnek egy másik "Y"  projekt módosításaival kapcsolatos információkra van szüksége. (Ha az X Java osztálya például az Y által biztosított felületet valósítja meg.)  X összeépítésekor az Y deltája a getDelta(Y) meghívásával áll rendelkezésre.  Annak biztosításához, hogy a platform szolgáltathasson ilyen változásokat, az X összeépítőjének deklarálnia kell az X és Y közötti függőségeket az Y-t tartalmazó tömb build() hívásból visszaadásával. Ha az összeépítő nem rendelkezik függőségekkel, akkor egyszerűen nullát ad vissza. További információkat az IncrementalProjectBuilder tartalmaz.

Teljes összeépítés

A teljes összeépítés kérés feldolgozásához szükséges logika bedolgozó-specifikus. Ez magában foglalja a projekt összes erőforrásának meglátogatását, vagy akár egyéb projektek megvizsgálását, ha függőségek vannak a projektek között. Az alábbi részlet bemutatja a teljes összeépítés egy lehetséges megvalósítását.

   protected void fullBuild(final IProgressMonitor monitor) throws CoreException {
      try {
         getProject().accept(new MyBuildVisitor());
      } catch (CoreException e) { }
   }

Az összeépítés-látogató végrehajtja az adott erőforrás összeépítését (és igaz választ ad az összes leszármazott erőforrás meglátogatására).

   class MyBuildVisitor implements IResourceVisitor {
      public boolean visit(IResource res) {
         //összeépíti a megadott erőforrást.
         //igaz értékkel tér vissza a leszármazott látogatásának folytatására.
         return true;
      }
   }

A látogatás folyamat addig folytatódik, amíg a teljes erőforrásfa be nincs járva.

Növekményes összeépítés

Növekményes összeépítés végrehajtásakor az összeépítő egy erőforrásmódosító-változást használ egy teljes erőforrásfa helyett.

   protected void incrementalBuild(IResourceDelta delta, 
         IProgressMonitor monitor) throws CoreException {
      // a látogató nem működik.
      delta.accept(new MyBuildDeltaVisitor());
   }

A látogatási folyamat addig folytatódik, amíg a teljes erőforrás-különbségfa be nincs járva. A módosítások természete hasonlít az Erőforrásmódosítás-figyelő részben leírthoz.  Egy fontos különbség, hogy növekményes projektösszeépítők esetén egy adott projektre, nem a teljes munkaterületre épülő erőforrásváltozást kezel.

Kiürítés összeépítés előtt

A munkaterület lehetővé teszi a felhasználók számára, hogy egy összeépítés kezdeményezése előtt kiürítsenek egy projektet vagy projektek halmazát. Ezen szolgáltatás segítségével a felhasználó adott projektek esetén kényszeríthet egy újraépítést teljesen elölről. Az összeépítőknek meg kell valósítaniuk ezt a metódust a problémajelzők vagy származtatott erőforrások kiürítéséhez a projektben.

Növekményes projektösszeépítő hozzárendelése egy projekthez

Ahhoz, hogy egy összeépítő rendelkezésre álljon egy adott projekthez, meg kell adni a projekt összeépítés-specifikációjában. A projekt összeépítési specifikációja a futtatandó parancsok listája sorrendben a projekt összeépítésekor. Minden parancs megnevez egy növekményes projektösszeépítőt.

MEGJEGYZÉS: Az összeépítés parancsban az összeépítő neve az összeépítő kiterjesztés teljes képzésű azonosítója. Egy kiterjesztés teljes képzésű azonosítója a bedolgozó azonosítójának és a plugin.xml fájlban lévő egyszerű kiterjesztési azonosítónak az egyesítésével kerül létrehozásra. Például a "com.pelda.osszeepitok" bedolgozóban lévő "sajat_osszeepito" egyszerű névvel rendelkező összeépítő neve "com.pelda.osszeepitok.sajat_osszeepito" lenne.

Az alábbi részlet hozzáad egy új összeépítőt elsődleges összeépítőként az összeépítők meglévő listájában.

   final String BUILDER_ID = "com.pelda.osszeepitok.sajat_osszeepito";
   IProjectDescription desc = project.getDescription();
   ICommand[] commands = desc.getBuildSpec();
   boolean found = false;

   for (int i = 0; i < commands.length; ++i) {
      if (commands[i].getBuilderName().equals(BUILDER_ID)) {
         found = true;
               break;
      }
   }
   if (!found) { 
      //összeépítő projekthez adása
      ICommand command = desc.newCommand();
      command.setBuilderName(BUILDER_ID);
      ICommand[] newCommands = new ICommand[commands.length + 1];

      // Hozzáadás más összeépítők előtt.
      System.arraycopy(commands, 0, newCommands, 1, commands.length);
      newCommands[0] = command;
      desc.setBuildSpec(newCommands);
      project.setDescription(desc, null);
   }

A projekt összeépítőjének beállítása csak egyszer történik meg, általában a projekt létrehozásakor.